React может пакетировать несколько вызовов setState и обрабатывать их все одновременно.И в вашем случае это происходит, потому что вы находитесь в обработчике событий (onClick).
Рендеринг выполняется только один раз (первоначальный рендеринг не включен), как вы можете видеть из фрагмента ниже.
Проблема Github о пакетной обработке React. Вызовы setState ()
Тем не менее можно использовать объект с 4 свойствами вместо 4-х переменных состояний.Но вы должны быть осторожны при обновлении состояния, потому что метод setState () не выполняет автоматическое слияние вашего последнего состояния с вашим новым свойством состояния.Он полностью заменяет состояние новым объектом, который вы передаете.
React Docs - Использование перехватчика состояний
Так что вам придется сделать что-то вроде этого:
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>