두 단계 모두에서 약간 다른 코드 블록을 사용하여 내 질문을 두 단계로 소개하겠습니다.
1 단계:
아래에는 2 초마다 자체적으로 렌더링되는 React 애플리케이션이 있으므로 브라우저가 콘솔에 렌더링 을 인쇄 하도록합니다. 사용자가 아무 키나 누르면 렌더링이 중지되고 콘솔 인쇄가 중지됩니다. 지금은 주석 처리 된 줄을 무시하십시오.
import { useState, useEffect, useRef } from 'react';
function App() {
const [number, setUpdate] = useState(0);
const [isPaused, setIsPaused] = useState(false);
const intervalRef = useRef(undefined);
useEffect(() => {
intervalRef.current = setInterval(() => setUpdate(prevNumber => ++prevNumber), 2000);
window.addEventListener('keydown', handleKeyDown);
}, []);
const handleKeyDown = () => {
clearInterval(intervalRef.current);
console.log('console log here');
// setIsPaused(isPaused);
};
console.log('render');
return null;
};
export default App;
위에서 일어난 일은 구성 요소를 5 번 렌더링 한 다음 키를 눌러 구성 요소의 렌더링을 중지 한 것입니다.
2 단계:
2 단계에서는 handleKeyDown에 설정된 상태를 주석 처리하지 않는 것을 제외하고는 정확히 동일한 애플리케이션이 있습니다.
const handleKeyDown = () => {
clearInterval(intervalRef.current);
console.log('console log here');
// This is no longer commented out. Why does it cause a new render?
setIsPaused(isPaused);
};
다음은 2 단계에서 코드를 변경 한 애플리케이션의 스크린 샷입니다.
다시 한 번, 키를 누른 후 구성 요소가 5 번 렌더링되도록했습니다. 그러나 이제 setIsPaused (isPaused)에 의해 상태가 변경되지 않아야하는 경우에도 추가 렌더링이 있습니다 (이미 상태에있는 것과 동일한 값을 설정했기 때문에 상태가 실제로 변경되지 않기 때문입니다 ) .
2 단계에서 추가 렌더링이 발생하는 이유가 무엇인지 이해하는 데 어려움이 있습니다. 분명한 것일까 요?
setIsPaused (isPaused) 는 나를 더욱 당황하게 만드는 setInterval에 의해 실행되는 다른 상태 변경을 주석 처리하면 새로운 렌더링을 발생시키지 않습니다.
이것은 알려진 기이 한 것 입니다. # 17474를 참조하십시오 . 새로운 동시 모드에서 도입 된 부작용입니다. 구성 요소 기능이 다시 실행되었지만 DOM은 변경되지 않은 상태로 유지됩니다.
나는 또한 사람들 이이 흥미로운 예를 게시하는 것을 발견했습니다 . 코드로 exp를 시도 할 수 있습니다. 구성 요소 함수에는 함수의 <div>{Math.random()}</div>
추가 재실행에서 난수가 변경되었지만 상태가 변경되지 않으면 DOM에 반영되지 않는 것과 같은 내용이 포함 됩니다.
결론. 이 부작용은 대부분 무해하다고 생각할 수 있습니다.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다