我是新来的,在此玩具问题中,控制台中显示了所选省份或所选城市的人口。我正在尝试使用特定值初始化省份状态,但该值会被覆盖,因为useEffect在render上运行了两次,第一次是正确的总体输出,第二次是空数组,如何更改代码以防止这是真的吗?
import React, { Fragment,useEffect, useState } from "react";
import useDropdown from "./useDropdown";
const canada_json=[
{
"name" : "Alberta",
"short" : "AB",
"population" : 4067175,
"capital" :"Edmonton",
"capital_population" : 981280
}
,
{
"name" : "British Columbia",
"short" : "BC",
"population" : 4648055,
"capital" : "Victoria",
"capital_population" : 92141
}]
const Provincelist = () => {
const [provinces, setprovinces] =useState([{value:{label: '', value : ""}}])
//Dropdown State I'm trying to initialise - Defined as useDropdown(label, defaultState, options)
const [province, ProvincesDropdown] = useDropdown("Provinces", "AB", provinces);
const [capitals, setcapitals] =useState([{value:{label: '', value : ""}}])
const [capital, CapitalsDropdown, setcapital] = useDropdown("Capitals","", capitals);
//Populates Province Dropdown
useEffect(() =>{
const options = canada_json.map(d => ({
"value" : d.short,
"label" : d.name
}))
setprovinces(options)
},[]);
//Populates Capital Dropdown after province selected and displays province population
useEffect(() =>{
const newlist = canada_json.filter(obj => obj.short === province)
const options = newlist.map(d => ({
"value" : d.short,
"label" : d.capital
}))
setcapitals(options)
const newlist2 = canada_json.filter(obj => obj.short === province).map((obj) => obj.population)
console.log(newlist2)
},[province]);
//If Capital Dropdown changes display capital population
useEffect(() =>{
const newlist = canada_json.filter(obj => obj.short === capital).map((obj) => obj.capital_population)
console.log(newlist)
},[capital]);
return (
<Fragment>
<ProvincesDropdown />
<CapitalsDropdown />
</Fragment>
)
}
export default Provincelist;
这是useDropDown的代码
import React, { useState } from "react";
const useDropdown = (label, defaultState, options) => {
const [state, updateState] = useState(defaultState);
const id = `use-dropdown-${label.replace(" ", "").toLowerCase()}`;
const Dropdown = () => (
<label htmlFor={id}>
{label}
<select
id={id}
value={state}
onChange={e => updateState(e.target.value)}
disabled={!options.length}
>
<option hidden>Please Select...</option>
{options.map(item => (
<option key={item.value} value={item.value}>
{item.label}
</option>
))}
</select>
</label>
);
return [state, Dropdown, updateState];
};
export default useDropdown;
答案 0 :(得分:0)
如果省份永远不会更新,请将其保存在useRef
人口需要更新,因此我们将其保存在useState
import React, { Fragment, useEffect, useState, useRef } from "react";
const canada_json = [
{
name: "Alberta",
short: "AB",
population: 4067175,
capital: "Edmonton",
capital_population: 981280
},
{
name: "British Columbia",
short: "BC",
population: 4648055,
capital: "Victoria",
capital_population: 92141
}
];
const Provincelist = () => {
const provinces = useRef(
canada_json.map((d) => ({
value: d.short,
label: d.name
}))
);
const [population, setpopulation] = useState("");
//Dropdown State I'm trying to initialise - Defined as useDropdown(label, defaultState, options)
const [province, ProvincesDropdown] = useDropdown(
"Provinces",
"AB",
provinces.current
);
const [capitals, setcapitals] = useState([
{ value: { label: "", value: "" } }
]);
const [capital, CapitalsDropdown] = useDropdown("Capitals", "", capitals);
//Populates Capital Dropdown after province selected and displays province population
useEffect(() => {
const newlist = canada_json.filter((obj) => obj.short === province);
const options = newlist.map((d) => ({
value: d.short,
label: d.capital
}));
setcapitals(options);
}, [province]);
useEffect(() => {
if (capital) {
const newPopulation = canada_json.find(
(province) => province.short === capital
).capital_population;
setpopulation(newPopulation);
}
}, [capital]);
return (
<Fragment>
<ProvincesDropdown />
<CapitalsDropdown />
<span>{population}</span>
</Fragment>
);
};
export default Provincelist;
答案 1 :(得分:0)
我注意到在您的.map
的两个useEffect
中,它返回的对象与{{1}的两个useState
的初始值形状都不匹配}}和provinces
capitals
应更改为:
const [provinces, setprovinces] = useState([{value: {label: '', value: ''}}]);
useEffect(() =>{
const options = canada_json.map(d => ({
"value" : d.short,
"label" : d.name
}))
setprovinces(options);
},[]);