我使用带有钩子的功能性react组件。
const [loaded, setLoaded] = React.useState(null);
const [title, setTitle] = React.useState(title);
React.useEffect(() => {
//...
fetch('https://jsonplaceholder.typicode.com/todos/1')
.then(response => response.json())
.then(json => {
setLoaded(true);
setTitle(title);
});
}, []);
在这种情况下,组件将呈现两次。一方面,这似乎是合乎逻辑的。
但是我在这个组件中也有一个复选框处理程序
const changeHandler = event => {
//...
setTotal(new_total);
setError(false);
};
在这种情况下,尽管状态也会更改2次,但不会进行两次渲染。我不明白为什么会这样。
PS
解决这个问题没有问题,我想知道为什么会这样
UPD :
如果我设置为useEffect
setLoaded(true);
setTitle(title);
setTitle2(title);
setTitle3(title);
将重新渲染4次,如果我在changeHandler
中设置
setTotal(new_total);
setError(false);
setError2(false);
setError3(false);
将进行1次重新渲染
答案 0 :(得分:2)
调用useState()
钩子的setter方法的副作用是,这样做会触发组件重新渲染。
避免冗余重新渲染的一种解决方案是像这样合并组件状态:
function functionalComponent() {
/* Merge both values into common "state object */
const [{ loaded, title }, setState] = React.useState({
loaded : null,
title : "inital title"
});
React.useEffect(() => {
/*
Single call to setState triggers on re-render only. The
value of "new title" for title could have been set in the
inital state, however I set it here to show how combined
state can be updated with a single call to setState()
*/
setState({ loaded : true, title : "new title" })
/*
setLoaded(true);
setTitle(title);
*/
}, []);
/* Use loaded and title variables as needed during render */
return <div>{ loaded } - { title }</div>
}
答案 1 :(得分:0)
React将事件处理程序包装在对
unstable_batchedUpdates()
,以便您的处理程序在 打回来。该回调内部触发的任何状态更新都将是 分批。在该回调之外触发的任何状态更新都不会 分批。超时,承诺和异步功能将最终执行 在该回调之外,因此无法批量处理。