React hook useRender 调用两次,如果 bailing 和之后设置状态
React hook useRender called twice if bailing and setting state afterward
我不确定这是否是预期的行为,但如果您在使用 useReducer 挂钩时退出分派 (https://reactjs.org/docs/hooks-reference.html#bailing-out-of-a-dispatch),则该操作会在其后跟渲染时发生两次。让我解释一下:
// bailing out to prevent re-rendering
const testReducer = (state, action) => {
switch (action.type) {
case "ADD":
state.test += 1
return state;
}
};
const myComponent = () => {
let [totalClicks, setClicks] = useState(0);
const [state, setState] = useReducer(testReducer, {
test: 0,
});
const clickHandler = () => {
setState({type: 'ADD'});
setClicks((totalClicks += 1));
};
return (
<div>
<button onClick={clickHandler}>+</button>
<p>{totalClicks}</p>
<p>test count: {state.test}</p>
</div>
);
}
当您单击按钮时,state.test 增加 2,而 totalClicks 增加 1。但是,如果我要更改 reducer,使其不会保释到 1如下所示,它们都会增加 1.
// non-bailing reducer
const testReducer = (state, action) => {
switch (action.type) {
case "ADD":
return {
test: state.test + 1,
};
}
};
这是为什么?这是预期的行为还是错误?
沙箱示例:https://codesandbox.io/s/sad-robinson-dds63?file=/src/App.js
更新:
在进行了一些调试之后,看起来这种行为只有在用 React.StrictMode
包装时才会发生
有谁知道这是什么原因造成的???
根据 doc of StrictMode,React 故意使用相同的操作两次调用 reducer 函数,以暴露未被注意的潜在有害副作用,这正是您的案例所发生的情况。
Strict mode can’t automatically detect side effects for you, but it can help you spot them by making them a little more deterministic. This is done by intentionally double-invoking the following functions: […] Functions passed to useState, useMemo, or useReducer
我不确定这是否是预期的行为,但如果您在使用 useReducer 挂钩时退出分派 (https://reactjs.org/docs/hooks-reference.html#bailing-out-of-a-dispatch),则该操作会在其后跟渲染时发生两次。让我解释一下:
// bailing out to prevent re-rendering
const testReducer = (state, action) => {
switch (action.type) {
case "ADD":
state.test += 1
return state;
}
};
const myComponent = () => {
let [totalClicks, setClicks] = useState(0);
const [state, setState] = useReducer(testReducer, {
test: 0,
});
const clickHandler = () => {
setState({type: 'ADD'});
setClicks((totalClicks += 1));
};
return (
<div>
<button onClick={clickHandler}>+</button>
<p>{totalClicks}</p>
<p>test count: {state.test}</p>
</div>
);
}
当您单击按钮时,state.test 增加 2,而 totalClicks 增加 1。但是,如果我要更改 reducer,使其不会保释到 1如下所示,它们都会增加 1.
// non-bailing reducer
const testReducer = (state, action) => {
switch (action.type) {
case "ADD":
return {
test: state.test + 1,
};
}
};
这是为什么?这是预期的行为还是错误? 沙箱示例:https://codesandbox.io/s/sad-robinson-dds63?file=/src/App.js
更新: 在进行了一些调试之后,看起来这种行为只有在用 React.StrictMode
包装时才会发生有谁知道这是什么原因造成的???
根据 doc of StrictMode,React 故意使用相同的操作两次调用 reducer 函数,以暴露未被注意的潜在有害副作用,这正是您的案例所发生的情况。
Strict mode can’t automatically detect side effects for you, but it can help you spot them by making them a little more deterministic. This is done by intentionally double-invoking the following functions: […] Functions passed to useState, useMemo, or useReducer