React에서 일괄 처리
React의
useState
hook이 가장 간단한 후크라고 생각할 수 있습니다. 그러나 약간의 복잡성이 있습니다.일괄 처리란 무엇입니까?
일괄 처리는
setState
에 대한 여러 호출이 하나의 상태 업데이트로만 그룹화되는 경우입니다.function App() {
const [count, setCount] = useState(0);
const [flag, setFlag] = useState(false);
useEffect(() => {
// only output once per click
console.log({ count, flag });
}, [count, flag]);
const handleClick = () => {
// Here, react will re-render only once
// Hence, the state updates are `batched`
setCount(c => c + 1);
setFlag(f => !f);
};
return (
<div className='App'>
<button onClick={handleClick}>Click Me!</button>
<h3 style={{ color: flag ? 'blue' : 'black' }}>Count: {count}</h3>
</div>
);
}
✅ See demo (batching inside event handlers) (버튼을 클릭하면 카운트와 플래그가 모두 변경되지만 콘솔 출력은 하나만 표시됨)
왜 일괄 처리 ?
일관되지 않은 일괄 처리 동작
그러나 React는 일괄 처리에 대해 일관성이 없었습니다. 예를 들어, async function/promise based API 에서,
React는 업데이트를 일괄 처리하지 않고 독립적인 업데이트가 발생합니다(두 번의 호출 수행
setState
).// little async function
const sleep = () => new Promise(resolve => setTimeout(resolve, 200));
export default function App() {
const [flag, setFlag] = useState(true);
const [count, setCount] = useState(0);
const handleClick = async () => {
// mimicing some async call
// (ex, fecthing data from server, etc.)
await sleep();
setFlag(f => !f);
setCount(c => c + 1);
};
useEffect(() => {
// in this case, two console logs can be seen
// since `setState` is called inside an asynchronous function
// So, React would not batch the updates, and perform two independent updates.
console.log({ count, flag });
// whenever `flag` or `count` changes, do somethig!
}, [count, flag]);
return (
<>
<h2>React's Batching Behavior while inside async callbacks</h2>;
<p>Count: {count}</p>
<button
onClick={handleClick}
style={{ backgroundColor: flag ? 'orange' : 'blue', color: '#fff' }}
>
Click me!
</button>
</>
);
}
⚠️ See demo (not batching updates inside async function) (버튼을 클릭하면 콘솔에 두 줄이 인쇄됨)
비동기 함수의 강제 일괄 처리
setState
이벤트 핸들러에서 업데이트를 일괄 처리하도록 하려면 unstable_batchedUpdates
(문서화되지 않은 API)를 사용할 수 있습니다.import { unstable_batchedUpdates } from 'react-dom';
unstable_batchedUpdates(() => {
setCount(c => c + 1);
setFlag(f => !f);
});
이는 React가 브라우저 이벤트(예: 클릭) 동안 일괄 업데이트에만 사용되기 때문입니다. 하지만 여기에서는 이벤트가 이미 처리된 후(aync 함수에서) 상태를 업데이트하고 있습니다.
데모는 React 17: forced batching outside of event handlers을 참조하십시오.
자동 배치 선택 해제
일부 코드는 상태 변경 직후 DOM에서 무언가를 읽는 것에 의존할 수 있습니다. 이러한 사용 사례의 경우 ReactDOM.flushSync을 사용하여 일괄 처리를 옵트아웃할 수 있습니다.
이전 예에서 계속해서
function App() {
const [count, setCount] = useState(0);
const [flag, setFlag] = useState(false);
useEffect(() => {
console.log({ count, flag });
}, [count, flag]);
const handleClick = () => {
// setCount((c) => c + 1);
// Force this state update to be synchronous.
ReactDOM.flushSync(() => setCount(c => c + 1));
// By this point, DOM is updated.
setFlag(f => !f);
};
return (
<div className='App'>
<button onClick={handleClick}>Click Me!</button>
<h3 style={{ color: flag ? 'blue' : 'black' }}>Count: {count}</h3>
</div>
);
}
참조⚠️ ReactDOM.flushSync: Opt out of automatic batching in event handlers
ReactDOM.flushSync
는 일반적이지 않으며 드물게 사용해야 합니다. flushSync flushes the entire tree and actually forces complete re-rendering for updates that happen inside of a call, so you should use it very sparingly. This way it doesn’t break the guarantee of internal consistency between props, state, and refs.
이 API의 비동기 동작 및 이유
setState
가 비동기인 이유에 대해 자세히 알아보려면 이 멋진 토론RFClarification: why is setState asynchronous? #11527을 확인하십시오.React 18의 자동 배치
React 18은 out-of-the-box improvements과 함께 일부
ReactDOMClient.createRoot
을 포함합니다.여기에는 자동 일괄 처리 지원이 포함됩니다.
Starting in React 18, all updates will be automatically batched, no matter where they originate from.
따라서 이벤트 핸들러, 비동기 함수, 시간 초과 또는 모든 함수 내부에서
setState
를 호출하면 자동으로 일괄 처리됩니다(내부 반응 이벤트와 동일).이렇게 하면 렌더링이 줄어들어 반응 애플리케이션의 성능이 향상됩니다.
function handleClick() {
fetchSomething().then(() => {
// React 18 and later DOES batch these:
setCount(c => c + 1);
setFlag(f => !f);
// React will only re-render once at the end (that's batching!)
});
}
ReactDOM.createRoot
가 있는 React 18에서만 작동합니다.ReactDOM.render
가 포함된 React 18은 이전 동작내 블로그에서 읽고 싶습니까? Checkout this blog post
Reference
이 문제에 관하여(React에서 일괄 처리), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/shivamjjha/batching-in-react-4pp3텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)