创建多个子组件,每个子组件都可以设置其父组件的状态,使这些子组件具有不同版本的状态历史(也称为陈旧状态)
重现错误:
- 点击“添加新社交媒体”创建 2 个子组件
- 提交两个子组件以设置父状态
- 再次提交第一个创建的组件,现在第二个组件输入从结果状态中消失
另一个错误:
- 点击“添加新社交媒体”创建 2 个子组件
- 提交二次创建的子组件
- 提交第一个创建的子组件,现在第二个组件输入从结果状态中消失
总而言之,我希望结果状态包含每个组件的所有数据。我该如何解决这个问题?
https://codesandbox.io/s/blissful-fog-oz10p
const Admin = () => {
const [links, setLinks] = useState({});
const [newLink, setNewLink] = useState([]);
const updateLinks = (socialMedia, url) => {
setLinks({
...links,
[socialMedia]: url
});
};
const linkData = {
links,
updateLinks
};
const applyChanges = () => {
console.log(links);
};
return (
<>
{newLink ? newLink.map(child => child) : null}
<div className="container-sm">
<Button
type="submit"
fullWidth
variant="contained"
color="primary"
onClick={() => {
setNewLink([
...newLink,
<AddNewLink key={Math.random()} linkData={linkData} />
]);
}}
>
Add new social media
</Button>
<Button
type="submit"
fullWidth
variant="contained"
color="primary"
style={{ marginTop: "50px" }}
onClick={() => applyChanges()}
>
Apply Changes
</Button>
<h3>{JSON.stringify(links, null, 4)}</h3>
</div>
</>
);
};
export default Admin;
const AddNewLink = props => {
const [socialMedia, setSocialMedia] = useState("");
const [url, setUrl] = useState("");
const { updateLinks } = props.linkData;
const handleSubmit = () => {
updateLinks(socialMedia, url);
};
return (
<>
<FormControl
style={{ marginTop: "30px", marginLeft: "35px", width: "90%" }}
>
<InputLabel>Select Social Media</InputLabel>
<Select
value={socialMedia}
onChange={e => {
setSocialMedia(e.target.value);
}}
>
<MenuItem value={"facebook"}>Facebook</MenuItem>
<MenuItem value={"instagram"}>Instagram</MenuItem>
<MenuItem value={"tiktok"}>TikTok</MenuItem>
</Select>
</FormControl>
<form
noValidate
autoComplete="off"
style={{ marginBottom: "30px", marginLeft: "35px" }}
>
<TextField
id="standard-basic"
label="Enter link"
style={{ width: "95%" }}
onChange={e => {
setUrl(e.target.value);
}}
/>
</form>
<div className="container-sm">
<Button
type="submit"
fullWidth
variant="contained"
color="primary"
style={{ marginBottom: "30px" }}
onClick={() => handleSubmit()}
>
Submit
</Button>
</div>
</>
);
};
export default AddNewLink;
最佳答案
您遇到的问题是由 updateLinks()
函数 关闭 links
状态引起的。
当您创建两个 AddNewLink
组件时,它们中的每一个都被传递给 updateLinks()
函数。因为最初,links
是一个空对象,updateLinks()
函数传递给 AddNewLink
的两个实例,在 links 上有一个闭包
变量和 links
当时指的是一个空对象 {}
。所以当你提交表单时,就updateLinks()
函数而言,links
是一个空对象。因此,当 links
与从 AddNewLink
组件传递的数据合并时,只有来自提交表单的数据被保存在状态中,因为 links
是一个空的对象。
解决方案:
您可以使用 useRef
Hook 在 updateLinks()
函数中访问 links
的最新值。
const Admin = () => {
...
const linkRef = useRef();
const updateLinks = (socialMedia, url) => {
linkRef.current = { ...linkRef.current, [socialMedia]: url };
setLinks(linkRef.current);
};
...
};
此外,我认为您不需要多个 AddNewLink
组件实例。您可以仅使用一个 AddNewLink
组件实例在状态中添加多个社交媒体链接。
演示:
关于javascript - react 如何修复子组件中的陈旧状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63086881/