我有一个用例,其中有 4 个选择的组件都共享相同的状态。问题是当用户从一个选项中选择一个选项时,其他选项不应显示该选项,依此类推。这个问题很简单并且已经解决了。这样做时,我正在更新共享状态,因此所有 4 个选择都由 react 重新渲染,因此我丢失了选择中的选定值。请参阅随附的 GIF。
有人可以指出一个解决方案,我可以使用最少的状态和更少的重新渲染来解决这个问题吗?
附上下面的完整代码:
const SendTroops = () => {
const [planets, setPlanets] = useState([]);
const [vehicles, setVehicles] = useState([]);
const constructState = (data) => {
const arr = [];
let obj = {};
for (let i = 0; i < 4; i++) {
obj[i] = data;
}
arr.push(obj);
return arr;
};
useEffect(() => {
const getPlanets = async () => {
try {
const response = await callAPI(PLANETS.url, PLANETS.method);
const data = await response.json();
setPlanets(constructState(data));
} catch (err) {
console.log(err);
}
}
const getVehicles = async () => {
try {
const response = await callAPI(VEHICLES.url, VEHICLES.method);
const data = await response.json();
setVehicles(constructState(data));
} catch (err) {
console.log(err);
}
};
getPlanets();
getVehicles();
}, []);
const ShowInputs = (n) => {
const options = [];
for (let i = 0; i < n; i++) {
options.push((
<div className="column" key={i}>
<Select
styles="select"
name={`destination${i}`}
options={(planets && planets[0]) ? planets[0][i] : []}
onSelect={(e) => onDestinationChange(e, i)} />
<Radio
styles="radio"
name={`vehicle${i}`}
options={(vehicles && vehicles[0]) ? vehicles[0][i] : []}
onSelect={(e) => onVehicleChange(e, i)} />
</div>
))
}
return options;
}
const onDestinationChange = (e, index) => {
const selectedName = e.target.value;
const values = Object.values(planets[0]);
let obj = {};
for (let i = 0; i < 4; i++) {
if (i === index) obj[i] = values[i];
else {
obj[i] = values[i].filter((value) => value.name !== selectedName);
}
}
const updatedPlanets = [].concat([obj]);
setPlanets(updatedPlanets);
};
const onVehicleChange = (e) => {
console.log(e.target.value);
};
const onReset = (e) => {
e.preventDefault();
};
return (
< main >
<p className="search-title">Select planets for your Troops to search</p>
<form>
<div className="row">
{ShowInputs(4)}
</div>
<div className="row button-group">
<Link to='/missionreport'>
<Button styles="button" type="submit" text="Find Falcone" />
</Link>
<Button styles="button" type="reset" text="Reset" onPress={onReset} />
</div>
</form>
</main >
);
};
最佳答案
只需记住行星列表中所选行星的索引和 select
的索引即可该行星已被选择的元素。然后仅在 select
上显示所选选项之前选择的位置。
这样您就必须向您的州添加另外 2 个字段:
- 行星列表中所选行星的索引(默认为
-1
或负数) - 索引
<select>
选择它的元素(在您的情况下,它是i
中for
循环的迭代器ShowInputs()
)。
然后在每次用户选择某些内容时更新该字段(使用 onDestinationChange()
)。
关于javascript - React 中的共享状态也会更新其余组件和当前组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59590951/