React Hooks의useEffect에서 setInterval 등을 호출할 때state 등 값이 변하지 않는 문제의 해결 방법
10593 단어 ReactJavaScriptTypeScript
먼저
다음 코드는state값이 변화할 때 어떤 동작을 할 것이라고 생각합니까?
본질이 아니기 때문에clearInterval
등의 처리는 생략되었다.const [x, setX] = useState(0);
useEffect(() => {
setInterval(() => {
console.log(x);
}, 1000);
}, []);
이 코드는 생각대로 움직이지 않고state의 값이 바뀌어도 0을 계속 출력합니다.
왜죠?JS의 폐쇄를 어느 정도 이해하는 사람이라면 알 것 같습니다.
구성 요소 함수가 호출될 때의 행동을 고려해 보세요.
첫 번째 호출에서 useState(0)
를 호출하면 x
에 0
의 값을 입력합니다.useEffect
의 리셋도 호출되었다.이때setInterval
의 리셋은 x
라는 변수를 포획했다.
두 번째 이후 호출 중 x
은 현재state (이 코드만 통해 구체적인 값을 알 수 없음)useEffect
의 두 번째 매개 변수는 []
이기 때문에 리셋을 호출하지 않습니다.
즉, setInterval
리셋된 x
은 항상 첫 번째 호출 때의 x
를 포획한다.
또 useState
는 오해하기 쉬운 부분으로 N차x
와 N차x
는 완전히 다른 변수다.React가 잘 관리되기 때문에 같은 변수로 보이지만 JS로 보면 완전히 다른 것이다.여기가 포인트야.
그래서 setInterval
의 리셋 포획된 x
은 항상 처음으로 호출된 값, 즉 0
이다.
해결 방법
그럼 어떻게 해결해야 되지?
사용 useRef
은 다음과 같습니다.const [x, setX] = useState(0);
const refX = useRef(x);
useEffect(() => {
refX.current = x;
}, [x]);
useEffect(() => {
setInterval(() => {
console.log(refX.current);
}, 1000);
}, []);
왜 이렇게 하면 순조롭게 진행될 수 있습니까?
우선 2행~5행에는 시종일관x
의 값을 refX.current
에 넣는 코드가 적혀 있다.
한편 이번 setInterval
의 리턴은 x
이 아니라 refX
이다.
이번에도 N차 호출과 N차 호출refX
은 완전히 다른 변수이지만 useRef
내부에서 느낌이 좋아서 refX
의 값은 항상 고정되어 있다.그래서 전혀 다른 변수라도 문제가 생기지 않는다.
또한 x
의 값이 refX
에 있는 코드는 자주 사용되기 때문에 사용자 정의 연결화를 해야 한다.export function useValueRef<T>(val: T) {
const ref = React.useRef(val);
React.useEffect(() => {
ref.current = val;
}, [val]);
return ref;
}
이걸로 하면 이렇게 돼요.const [x, setX] = useState(0);
const refX = useValueRef(x);
useEffect(() => {
setInterval(() => {
console.log(refX.current);
}, 1000);
}, []);
경우에 따라 단순화된 솔루션
방금 포획할 변수를 인용하여 해결했습니다.
하지만 변수가 늘어나면 힘들어요.
그래서 이번에 우리는 함수를 참고한다.const [x, setX] = useState(0);
const f = useValueRef(() => {
console.log(x);
});
useEffect(() => {
setInterval(() => {
f.current();
}, 1000);
}, []);
첫 번째 코드 예에서는 최신 x
을 캡처하는 데 사용되는 엔클로저를 항상 생성합니다.
그러나 useEffect
의 두 번째 파라미터는 []
이어서 사용하지 않고 버려졌다.
이번에는 이걸 효과적으로 이용해서 해결할게요.f.current
는 항상 최신 x
엔클로저를 캡처합니다.f
라는 이름이 오염되면 번거롭기 때문에 아래의 사용자 정의 연결고리를 만들어 청소하세요.export function useEffectRef<T>(effect: (ref: React.MutableRefObject<T>) => void | (() => void | undefined), val: T, deps?: React.DependencyList) {
const ref = useValueRef(val);
React.useEffect(() => effect(ref), deps);
}
이걸로 하면 이렇게 돼요.
const [x, setX] = useState(0);
useEffectRef(f => {
setInterval(() => {
f.current();
},1000);
}, () => {
console.log(x);
}, []);
이렇게 하면 변수 증가도 쉽다.
Reference
이 문제에 관하여(React Hooks의useEffect에서 setInterval 등을 호출할 때state 등 값이 변하지 않는 문제의 해결 방법), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/kgtkr/items/374e2b676c953f14ec99
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
const [x, setX] = useState(0);
useEffect(() => {
setInterval(() => {
console.log(x);
}, 1000);
}, []);
그럼 어떻게 해결해야 되지?
사용
useRef
은 다음과 같습니다.const [x, setX] = useState(0);
const refX = useRef(x);
useEffect(() => {
refX.current = x;
}, [x]);
useEffect(() => {
setInterval(() => {
console.log(refX.current);
}, 1000);
}, []);
왜 이렇게 하면 순조롭게 진행될 수 있습니까?우선 2행~5행에는 시종일관
x
의 값을 refX.current
에 넣는 코드가 적혀 있다.한편 이번
setInterval
의 리턴은 x
이 아니라 refX
이다.이번에도 N차 호출과 N차 호출
refX
은 완전히 다른 변수이지만 useRef
내부에서 느낌이 좋아서 refX
의 값은 항상 고정되어 있다.그래서 전혀 다른 변수라도 문제가 생기지 않는다.또한
x
의 값이 refX
에 있는 코드는 자주 사용되기 때문에 사용자 정의 연결화를 해야 한다.export function useValueRef<T>(val: T) {
const ref = React.useRef(val);
React.useEffect(() => {
ref.current = val;
}, [val]);
return ref;
}
이걸로 하면 이렇게 돼요.const [x, setX] = useState(0);
const refX = useValueRef(x);
useEffect(() => {
setInterval(() => {
console.log(refX.current);
}, 1000);
}, []);
경우에 따라 단순화된 솔루션
방금 포획할 변수를 인용하여 해결했습니다.
하지만 변수가 늘어나면 힘들어요.
그래서 이번에 우리는 함수를 참고한다.const [x, setX] = useState(0);
const f = useValueRef(() => {
console.log(x);
});
useEffect(() => {
setInterval(() => {
f.current();
}, 1000);
}, []);
첫 번째 코드 예에서는 최신 x
을 캡처하는 데 사용되는 엔클로저를 항상 생성합니다.
그러나 useEffect
의 두 번째 파라미터는 []
이어서 사용하지 않고 버려졌다.
이번에는 이걸 효과적으로 이용해서 해결할게요.f.current
는 항상 최신 x
엔클로저를 캡처합니다.f
라는 이름이 오염되면 번거롭기 때문에 아래의 사용자 정의 연결고리를 만들어 청소하세요.export function useEffectRef<T>(effect: (ref: React.MutableRefObject<T>) => void | (() => void | undefined), val: T, deps?: React.DependencyList) {
const ref = useValueRef(val);
React.useEffect(() => effect(ref), deps);
}
이걸로 하면 이렇게 돼요.
const [x, setX] = useState(0);
useEffectRef(f => {
setInterval(() => {
f.current();
},1000);
}, () => {
console.log(x);
}, []);
이렇게 하면 변수 증가도 쉽다.
Reference
이 문제에 관하여(React Hooks의useEffect에서 setInterval 등을 호출할 때state 등 값이 변하지 않는 문제의 해결 방법), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/kgtkr/items/374e2b676c953f14ec99
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
const [x, setX] = useState(0);
const f = useValueRef(() => {
console.log(x);
});
useEffect(() => {
setInterval(() => {
f.current();
}, 1000);
}, []);
export function useEffectRef<T>(effect: (ref: React.MutableRefObject<T>) => void | (() => void | undefined), val: T, deps?: React.DependencyList) {
const ref = useValueRef(val);
React.useEffect(() => effect(ref), deps);
}
const [x, setX] = useState(0);
useEffectRef(f => {
setInterval(() => {
f.current();
},1000);
}, () => {
console.log(x);
}, []);
Reference
이 문제에 관하여(React Hooks의useEffect에서 setInterval 등을 호출할 때state 등 값이 변하지 않는 문제의 해결 방법), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/kgtkr/items/374e2b676c953f14ec99텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)