[英]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.