使用多个 setHook 让组件渲染不止一次?
Using multiple setHook makes component render more than once?
如果我有很多 useState
并且在单击一个按钮时我调用多个 setHook
,它会呈现多次还是只呈现一次?
例如
export default function setMultipleHooks() {
const [hook1, setHook1] = useState(false)
const [hook2, setHook2] = useState(false)
const [hook3, setHook3] = useState(false)
const [hook4, setHook4] = useState(false)
const setHooks = () => {
setHook1(true)
setHook2(true)
setHook3(true)
setHook4(true)
}
return (
<button onClick={setHooks} >Hey</button>
)
}
单击按钮后,它会渲染多少次? 1 或 4 次?
通常为了检查组件渲染了多少次,我只是在 render
方法中放了一个 console.log
,但是对于功能组件,我不确定如何测试它。
如果渲染4次,如果4个钩子总是相关的,只用一个useState
(传递一个对象)会更好吗?
React 可以批处理多个 setState 调用并一次渲染它们。在您的情况下,它会这样做,因为您在事件处理程序 (onClick) 中。
它只渲染一次(不包括初始渲染),如下面的代码片段所示。
Github issue about React batching setState() calls
您仍然可以使用具有 4 个属性的对象而不是 4 个状态挂钩变量。但是在更新状态时你必须小心,因为 hook 的 setState() 不会自动将你的最后状态与你的新状态合并 属性。它用您传递的新对象完全替换状态。
React Docs - Using the state hook
所以你必须这样做:
function YourComponent() {
const INITIAL_STATE = {a: false, b: false, c: false, d: false};
const [state,setState] = useState(INITIAL_STATE);
function handleClick() {
setState((prevState) => {
return({
...prevState,
b: true
});
});
}
}
const { useState, useRef, useEffect } = React;
function App() {
const renderTimes = useRef(0);
const [hook1, setHook1] = useState(false);
const [hook2, setHook2] = useState(false);
const [hook3, setHook3] = useState(false);
const [hook4, setHook4] = useState(false);
const setHooks = () => {
setHook1(true);
setHook2(true);
setHook3(true);
setHook4(true);
}
useEffect( () => {
renderTimes.current+=1;
});
return (
<div>
<div>I rendered {renderTimes.current} time(s).</div>
<div>NOTE: The initial render is not included.</div>
<div>State hook1 is equal to: {hook1.toString()}</div>
<div>State hook2 is equal to: {hook2.toString()}</div>
<div>State hook3 is equal to: {hook3.toString()}</div>
<div>State hook4 is equal to: {hook4.toString()}</div>
<button onClick={setHooks}>Click</button>
</div>
);
}
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root"></div>
Normally to check how many times the component is rendering, I just put a console.log in the render method, but with functional components, I'm not sure how to test this.
把console.log放在函数里面就行了(函数本身就是render
方法)。
它只会呈现一次,因为有一个很小的时间间隔,如果多次调用 useState setter,它们的更新将被分批处理。
If it renders 4 times, it would be better to use only one useState (passing an object) if the 4 hooks are always related?
如果你有复杂的状态,你真的应该考虑 useReducer
。
更多:
如果我有很多 useState
并且在单击一个按钮时我调用多个 setHook
,它会呈现多次还是只呈现一次?
例如
export default function setMultipleHooks() {
const [hook1, setHook1] = useState(false)
const [hook2, setHook2] = useState(false)
const [hook3, setHook3] = useState(false)
const [hook4, setHook4] = useState(false)
const setHooks = () => {
setHook1(true)
setHook2(true)
setHook3(true)
setHook4(true)
}
return (
<button onClick={setHooks} >Hey</button>
)
}
单击按钮后,它会渲染多少次? 1 或 4 次?
通常为了检查组件渲染了多少次,我只是在 render
方法中放了一个 console.log
,但是对于功能组件,我不确定如何测试它。
如果渲染4次,如果4个钩子总是相关的,只用一个useState
(传递一个对象)会更好吗?
React 可以批处理多个 setState 调用并一次渲染它们。在您的情况下,它会这样做,因为您在事件处理程序 (onClick) 中。
它只渲染一次(不包括初始渲染),如下面的代码片段所示。
Github issue about React batching setState() calls
您仍然可以使用具有 4 个属性的对象而不是 4 个状态挂钩变量。但是在更新状态时你必须小心,因为 hook 的 setState() 不会自动将你的最后状态与你的新状态合并 属性。它用您传递的新对象完全替换状态。
React Docs - Using the state hook
所以你必须这样做:
function YourComponent() {
const INITIAL_STATE = {a: false, b: false, c: false, d: false};
const [state,setState] = useState(INITIAL_STATE);
function handleClick() {
setState((prevState) => {
return({
...prevState,
b: true
});
});
}
}
const { useState, useRef, useEffect } = React;
function App() {
const renderTimes = useRef(0);
const [hook1, setHook1] = useState(false);
const [hook2, setHook2] = useState(false);
const [hook3, setHook3] = useState(false);
const [hook4, setHook4] = useState(false);
const setHooks = () => {
setHook1(true);
setHook2(true);
setHook3(true);
setHook4(true);
}
useEffect( () => {
renderTimes.current+=1;
});
return (
<div>
<div>I rendered {renderTimes.current} time(s).</div>
<div>NOTE: The initial render is not included.</div>
<div>State hook1 is equal to: {hook1.toString()}</div>
<div>State hook2 is equal to: {hook2.toString()}</div>
<div>State hook3 is equal to: {hook3.toString()}</div>
<div>State hook4 is equal to: {hook4.toString()}</div>
<button onClick={setHooks}>Click</button>
</div>
);
}
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root"></div>
Normally to check how many times the component is rendering, I just put a console.log in the render method, but with functional components, I'm not sure how to test this.
把console.log放在函数里面就行了(函数本身就是render
方法)。
它只会呈现一次,因为有一个很小的时间间隔,如果多次调用 useState setter,它们的更新将被分批处理。
If it renders 4 times, it would be better to use only one useState (passing an object) if the 4 hooks are always related?
如果你有复杂的状态,你真的应该考虑 useReducer
。
更多: