리액트 훅 - 상태가 변경되지 않았는데도 useEffect가 실행됩니다.
다른 상태 속성이 변경되면 보기가 변경되는 효과를 내 구성 요소 내부에 설정했습니다.그러나 어떤 이유에서인지 컴포넌트가 마운트되면 효과가 실행됩니다.detailIndex변경되지 않았습니다.
const EventsSearchList = () => {
const [view, setView] = useState('table');
const [detailIndex, setDetailIndex] = useState(null);
useEffect(() => {
console.log('onMount', detailIndex);
// On mount shows "null"
}, []);
useEffect(
a => {
console.log('Running effect', detailIndex);
// On mount shows "null"!! Should not have run...
setView('detail');
},
[detailIndex]
);
return <div>123</div>;
};
왜 이런 일이 생기는 건가요?
업데이트: 명확하지 않은 경우 컴포넌트 업데이트 시 이펙트를 실행하려고 합니다.detailIndex변화들.마운트되면 안 돼
useEffectfrom React Hooks는 기본적으로 모든 렌더링에 대해 실행되지만, 두 번째 매개 변수를 사용하여 효과를 다시 실행할 시기를 정의할 수 있습니다.즉, 이 기능은 항상 마운트 상에서 실행됩니다.고객님의 경우 두 번째useEffect시작 시 및 실행 시간detailIndex변화들.
상세정보 : https://reactjs.org/docs/hooks-effect.html
출처:
경험이 풍부한 JavaScript 개발자는 useEffect에 전달된 함수가 렌더링마다 다르다는 것을 알 수 있습니다.[...] 재렌더 간에 특정 값이 변경되지 않았다면 이펙트 적용을 건너뛰도록 React에게 지시할 수 있습니다.그러기 위해서는 배열을 useEffect의 두 번째 옵션 인수로 전달합니다.[...]
제 경우에서 두 번째 인수를 사용했는데도 컴포넌트가 계속 업데이트되었습니다.useEffect()그리고 나는 그것이 변하지 않고 변하지 않는 것을 확인하기 위해 인수를 인쇄하고 있었다.문제는 컴포넌트를 렌더링하고 있다는 것입니다.map()그리고 키가 바뀐 경우도 있고, 키가 바뀌면 반응하기 위해 전혀 다른 대상이 됩니다.
두 번째 가드를 추가하여 detailIndex가 초기값에서 -1로 변경되었는지 확인할 수 있습니다.
useEffect(
a => {
if(detailIndex != -1)
{ console.log('Running effect', detailIndex);
// On mount shows "null"!! Should not have run...
setView('detail');
}},
[detailIndex]);
코드를 확인하는 한 가지 방법useEffect종속성이 변경되었을 때만 실행되며 초기 마운트(첫 번째 렌더)에서는 사용되지 않습니다.이 경우 처음에 할당된 변수를 할당합니다.false이 될 뿐이다true 첫 번째 렌더링 후 이 변수는 당연히 후크여야 하므로 구성요소의 수명 동안 메모됩니다.
3종류의 비교useEffect:
const {useEffect, useRef, useState} = React
const App = () => {
const mountedRef = useRef() // ← the "flag"
const [value, setValue] = useState(false) // simulate a state change
// with the trick
useEffect(() => {
if (mountedRef.current){ // ← the trick
console.log("trick: changed")
}
}, [value])
// without the trick
useEffect(() => {
console.log("regular: changed")
}, [value])
// fires once & sets "mountedRef" ref to "true"
useEffect(() => {
console.log("rendered")
mountedRef.current = true
// update the state after some time
setTimeout(setValue, 1000, true)
}, [])
return null
}
ReactDOM.render(<App/>, document.getElementById("root"))
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root"></div>
if 및 if의 경우useEffect의 두 번째 파라미터 상태가 참조(값이 아님)에 따라 변화하면 효과가 발생합니다.
import React, { useState, useEffect } from 'react';
function App() {
const [x, setX] = useState({ a: 1 });
useEffect(() => {
console.log('x');
}, [x]);
setInterval(() => setX({ a: 1 }), 1000);
return <div></div>
}
}
export default App;
이 코드 스니펫에서는 로그가 매초 인쇄됩니다.왜냐하면 매초마다setX({a: 1})라고 합니다.x상태가 새 개체에 대한 새 참조로 업데이트됩니다.
ifsetX({a: 1})에 의해 대체되었습니다.setX(1)는 주기적으로
useEffect는 항상 초기 렌더링 후에 실행됩니다.
문서로부터:
모든 렌더링 후에 useEffect가 실행됩니까?예! 기본적으로 첫 번째 렌더링 후와 매번 업데이트 후에 모두 실행됩니다.(커스터마이즈 방법에 대해서는 나중에 설명하겠습니다)."마운트" 및 "업데이트"의 관점에서 생각하는 대신 효과가 "렌더링 후"로 생각하기가 더 쉽습니다.React는 효과를 실행할 때까지 DOM이 업데이트되었음을 보증합니다.
되지 않았으므로 다음 은 한 됩니다.useEffect는 종속성의 선택적 배열을 두 번째 인수로 받아들입니다).
useEffect(() => {
console.log('onMount', detailIndex);
// On mount shows "null" -> since default value for detailIndex is null as seen above
// const [detailIndex, setDetailIndex] = useState(null);
}, []);
그리고 이 효과는 초기 렌더링 후 리 고 과 더 기 와 음 더 됩 거 니 리 두 다 this and render트 모 after will effect the시 and the triggerdetailIndex changes (try calling 변경(호출 시도)setDetailIndex within the previous 이전 범위 내에서useEffect):):
useEffect(() =>
// ... effect code
}, [detailIndex]);
언급URL : https://stackoverflow.com/questions/54923896/react-hooks-useeffect-fires-even-though-the-state-did-not-change
'programing' 카테고리의 다른 글
| AJAX 및 jQuery와 함께 HTML5 파일 업로드 사용 (0) | 2023.03.25 |
|---|---|
| 일부 숫자가 ajax 객체의 URL에 추가되는 이유와 이를 제거하는 방법 (0) | 2023.03.25 |
| 모든 이력 스테이트에 대해 react-router routed-component를 유지합니다. (0) | 2023.03.25 |
| 요구가 AJAX인지 아닌지를 Rails가 검출합니다. (0) | 2023.03.25 |
| jQuery ajax 업로드 파일(asp.net mvc) (0) | 2023.03.25 |