[英]Why lifting an updated state from a child to a parent component does not work?
在切換孩子的 state 后嘗試更新父組件的 UI 時,我設法達到了我想要的結果,但是,作為 React 初學者,我想我做得不太對。
正如您將在下面的代碼中看到的,我根據event.target.value
更新了單選按鈕組件的 state,然后通過onToggle
道具使用SitePageToggle ( WebsitePicker ) 將其提升到組件。 問題是,根據我的理解,我應該使用selectedRadioBtn
及其更新的 state。但是,當我通過selectedRadioBtn
以便我可以根據它來確定我的QAObject
變量的 state 時,“網站”和“頁面”之間的切換順序' 被搞砸了和顛倒了。 如果我在子組件本身中使用更新的 state,這不是問題。
我知道[狀態更新可能是異步的][1],但是通過接受回調使用 useState 鈎子第二個版本也沒有解決問題。
這是父組件中的代碼:
import styles from "./WebsitePicker.module.css";
import { useState } from "react";
import SitePageToggle from "./SitePageToggle";
import SubmitButton from "./Buttons/SubmitButton";
function WebsitePicker() {
const [QAObject, setQAObject] = useState("Website");
const { label, input__url } = styles;
const toggleWebsitePageHandler = toggleData => {
if (toggleData === 'Website') {
setQAObject("Website");
} else {
setQAObject("Page");
}
};
return (
<>
<SitePageToggle onToggle={toggleWebsitePageHandler} />
<form onSubmit={formSubmissionHandler}>
<label className={label} htmlFor="picker">
Enter the URL of the {QAObject} you wish to QA.
</label>
<br />
<input
id="picker"
type="url"
className={input__url}
/>
<SubmitButton>QA my page</SubmitButton>
</form>
</>
);
}
export default WebsitePicker;
這是子組件中的代碼:
import RadioButton from "./Buttons/RadioButton";
function SitePageToggle({ onToggle }) {
const [selectedRadioBtn, setSelectedRadioBtn] = useState("Website");
const isRadioSelected = (btnValue) => selectedRadioBtn === btnValue;
const handleToggle = event => {
setSelectedRadioBtn(event.target.value);
onToggle(event.target.value);
};
return (
<ul>
<li>
<RadioButton
label="Website"
name="react-radio-btn"
value="Website"
checked={isRadioSelected("Website")}
onChange={handleToggle}
/>
</li>
<li>
<RadioButton
label="Page"
name="react-radio-btn"
value="Page"
checked={isRadioSelected("Page")}
onChange={handleToggle}
/>
</li>
</ul>
);
}
export default SitePageToggle;
[1]: https://reactjs.org/docs/state-and-lifecycle.html#state-updates-may-be-asynchronous
不確定我是否完全理解用例,但如果目標是將selectedRadioBtn
state提升到父級(而不是同步兩個狀態),那么SitePageToggle
可能不需要保留 state 的單獨副本,而是從父母。
快速簡化演示: stackblitz
在WebsitePicker
QAObject
作為selectedRadioBtn
傳遞:
<SitePageToggle
selectedRadioBtn={QAObject}
onToggle={toggleWebsitePageHandler}
/>
在SitePageToggle
,使用道具中的selectedRadioBtn
作為 state:
import RadioButton from "./Buttons/RadioButton";
function SitePageToggle({ selectedRadioBtn, onToggle }) {
const isRadioSelected = (btnValue) => selectedRadioBtn === btnValue;
const handleToggle = (event) => {
onToggle(event.target.value);
};
return (
<ul>
<li>
<RadioButton
label="Website"
name="react-radio-btn"
value="Website"
checked={isRadioSelected("Website")}
onChange={handleToggle}
/>
</li>
<li>
<RadioButton
label="Page"
name="react-radio-btn"
value="Page"
checked={isRadioSelected("Page")}
onChange={handleToggle}
/>
</li>
</ul>
);
}
export default SitePageToggle;
要正確傳遞子項 state selectedRadioBtn
,您應該使用 useEffect()。 useEffect 的第二個參數是依賴數組,所以只要selectedRadioBtn
發生變化,它就會觸發。
import RadioButton from "./Buttons/RadioButton";
function SitePageToggle({ onToggle }) {
const [selectedRadioBtn, setSelectedRadioBtn] = useState("Website");
const isRadioSelected = (btnValue) => selectedRadioBtn === btnValue;
const handleToggle = event => {
setSelectedRadioBtn(event.target.value);
// onToggle(event.target.value); <-- delete this here
};
useEffect(() => {
onToggle(selectedRadioBtn);
}, [selectedRadioBtn]);
return (
<>...</>
);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.