[英]React how to fix stale state in child component
創建多個子組件,每個子組件都可以設置其父組件的狀態,使這些子組件具有不同版本的 state 歷史(又名陳舊狀態)
要重現錯誤:
另一個錯誤:
總而言之,我希望生成的 state 擁有每個組件的所有數據。 我怎樣才能解決這個問題?
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()
function關閉links
state 引起的。
當您創建兩個AddNewLink
組件時,每個組件都會傳遞updateLinks()
function。 由於最初, links
是一個空的 object, updateLinks()
function 傳遞給AddNewLink
的兩個實例,對links
變量有一個閉包,當時的links
是指一個空的 ZA8CFDE6331BD59EB2AC96F8911C4B6 {}
6。 因此,當您提交表單時,就updateLinks()
function 而言, links
是一個空的 object。 因此,當將links
與從AddNewLink
組件傳遞的數據合並時,只有來自提交表單的數據會保存在 state 中,因為links
是一個空的 object。
解決方案:
您可以使用useRef
掛鈎訪問updateLinks()
function 中links
的最新值。
const Admin = () => {
...
const linkRef = useRef();
const updateLinks = (socialMedia, url) => {
linkRef.current = { ...linkRef.current, [socialMedia]: url };
setLinks(linkRef.current);
};
...
};
此外,我認為您不需要多個AddNewLink
組件實例。 您可以在 state 中添加多個社交媒體鏈接,只需一個AddNewLink
組件實例。
演示:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.