javascript - 我可以在反应中使用 useEffect 钩子在父级中设置状态吗
问题描述
我在子组件中有一组按钮,单击时设置相应的状态值 true 或 false。我在这个子组件中有一个 useEffect 钩子,它还依赖于所有这些状态值,所以如果单击一个按钮,这个钩子然后调用 setFilter ,它作为来自父级的道具传递下来......
const Filter = ({ setFilter }) => {
const [cycling, setCycling] = useState(true);
const [diy, setDiy] = useState(true);
useEffect(() => {
setFilter({
cycling: cycling,
diy: diy
});
}, [cycling, diy]);
return (
<Fragment>
<Row>
<Col>
<Button block onClick={() => setCycling(!cycling)}>cycling</Button>
</Col>
<Col>
<Button block onClick={() => setdIY(!DIY)}>DIY</Button>
</Col>
</Row>
</Fragment>
);
};
在父组件中,我显示了一个项目列表。我在父级中有两种效果,一种是初始加载项目,另一种是在更改过滤器时触发。为了简洁起见,我删除了大部分代码,但我认为我遇到的问题归结为这样一个事实,即在渲染我的 ItemDashboard 时,过滤器被调用了两次。我怎样才能阻止这种情况的发生,或者我应该以另一种方式看待这个问题。
const ItemDashboard = () => {
const [filter, setFilter] = useState(null);
useEffect(() => {
console.log('on mount');
}, []);
useEffect(() => {
console.log('filter');
}, [filter]);
return (
<Container>..
<Filter setFilter={setFilter} />
</Container>
);
}
解决方案
我猜,您正在寻找将状态提升到共同父母的方法。
为了做到这一点,您可以将子组件的事件处理程序(作为道具传递)绑定到其共同父级中所需的回调。
以下现场演示演示了该概念:
const { render } = ReactDOM,
{ useState } = React
const hobbies = ['cycling', 'DIY', 'hiking']
const ChildList = ({list}) => (
<ul>
{list.map((li,key) => <li {...{key}}>{li}</li>)}
</ul>
)
const ChildFilter = ({onFilter, visibleLabels}) => (
<div>
{
hobbies.map((hobby,key) => (
<label {...{key}}>{hobby}
<input
type="checkbox"
value={hobby}
checked={visibleLabels.includes(hobby)}
onChange={({target:{value,checked}}) => onFilter(value, checked)}
/>
</label>))
}
</div>
)
const Parent = () => {
const [visibleHobbies, setVisibleHobbies] = useState(hobbies),
onChangeVisibility = (hobby,visible) => {
!visible ?
setVisibleHobbies(visibleHobbies.filter(h => h != hobby)) :
setVisibleHobbies([...visibleHobbies, hobby])
}
return (
<div>
<ChildList list={visibleHobbies} />
<ChildFilter onFilter={onChangeVisibility} visibleLabels={visibleHobbies} />
</div>
)
}
render (
<Parent />,
document.getElementById('root')
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.12.0/umd/react.production.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.11.0/umd/react-dom.production.min.js"></script><div id="root"></div>
推荐阅读
- java - 如何在收音机和 DocuSign 的文本之间进行此呼叫
- c++ - 有没有办法确保对 BOOST_TESTs 消息进行惰性评估?
- python - 如何使用 re.sub 删除方括号内的重复文本块?
- python - 正则表达式 (Python) - 使用 Look-Behind 绕过量词?
- java - 我的 spring 应用程序启动不会停止运行
- python - Python:如何使用字典将运算符的字符串表示形式分配给数学运算符?
- java - 即使在设置 v4 签名之后,AWS 异常“使用 AWS KMS 托管密钥指定服务器端加密的请求也需要 AWS 签名版本 4”
- apache-kafka - Kafka Connect 中的孤立任务
- apache-flink - 配置 Flink 并行性的正确方法是什么?
- javascript - 将UMD格式第三方库导入Svelte