다른 상태에 의존하는 상태가 있다고 가정 해 보겠습니다 (예 : A가 변경되면 B가 변경되기를 원합니다).
A를 관찰하고 useEffect 후크 내부에 B를 설정하는 후크를 만드는 것이 적절합니까?
버튼을 클릭하면 첫 번째 효과가 발생하여 다음 렌더링 전에 b가 변경되어 두 번째 효과가 발생하도록 효과가 계단식으로 표시됩니까? 이와 같은 코드를 구조화하는 데 성능 저하가 있습니까?
let MyComponent = props => {
let [a, setA] = useState(1)
let [b, setB] = useState(2)
useEffect(
() => {
if (/*some stuff is true*/) {
setB(3)
}
},
[a],
)
useEffect(
() => {
// do some stuff
},
[b],
)
return (
<button
onClick={() => {
setA(5)
}}
>
click me
</button>
)
}
답변
효과는 항상 렌더링 단계가 완료된 후에 실행됩니다. 한 효과 내에서 State를 설정하더라도 다른 효과는 업데이트 된 상태를 읽고 렌더링 단계 후에 만 작업을 수행합니다.
동일한 논리를 실행하려는 경우 b
이외에 다른 이유로 인해 변경 될 수 있는 가능성이없는 한 동일한 효과로 두 작업을 모두 수행하는 것이 더 좋습니다.changing a
답변
일반적으로 setState
내부 useEffect
를 사용하면 원하지 않는 무한 루프가 생성됩니다. 나중에 다루게 될 규칙에는 몇 가지 예외가 있습니다.
useEffect
는 각 렌더링 후 호출되고 setState
내부에서 사용되면 구성 요소가 다시 렌더링되어 호출 useEffect
등을 수행합니다.
useState
inside of 를 사용 useEffect
하면 무한 루프가 발생하지 않는 인기있는 경우 중 하나는 useEffect
like에 대한 두 번째 인수로 빈 배열을 전달할 때 useEffect(() => {....}, [])
입니다. 즉, 효과 함수는 첫 번째 마운트 / 렌더링 이후에만 한 번 호출되어야합니다. 구성 요소에서 데이터 가져 오기를 수행하고 요청 데이터를 구성 요소의 상태로 저장하려는 경우 널리 사용됩니다.
답변
향후 목적을 위해 다음도 도움이 될 수 있습니다.
useEffect
이미 설명한대로 루프를 생성하지 않도록주의를 기울여야 하는 경우 setState를 사용 하는 것이 좋습니다.
그러나 이것이 발생할 수있는 유일한 문제는 아닙니다. 아래를 참조하십시오.
부모로부터 Comp
받는 구성 요소 가 props
있고 의 상태 props
를 설정하려는 변경 에 따라 있다고 상상해보십시오 Comp
. 어떤 이유로 각 소품마다 다른 변경해야합니다 useEffect
.
하지 마십시오
useEffect(() => {
setState({ ...state, a: props.a });
}, [props.a]);
useEffect(() => {
setState({ ...state, b: props.b });
}, [props.b]);
이 예에서 볼 수 있듯이 https://codesandbox.io/s/confident-lederberg-dtx7w 에서 볼 수 있듯이 상태를 변경하지 않을 수 있습니다.
때문에이 예에서 일어나는 이유는 그건 모두 useEffects이 같은 실행주기를 반응 은 모두 변경할 때 prop.a
와 prop.b
의 가치, 그래서 {...state}
당신이 할 때이 setState
정확히 모두에서 동일 useEffect
는 같은 맥락에서 때문이다. 두 번째를 실행 setState
하면 첫 번째setState
.
이 대신 수행
이 문제에 대한 해결책은 기본적으로 다음 setState
과 같이 호출하는 것입니다.
useEffect(() => {
setState(state => ({ ...state, a: props.a }));
}, [props.a]);
useEffect(() => {
setState(state => ({ ...state, b: props.b }));
}, [props.b]);
여기에서 솔루션을 확인하십시오 : https://codesandbox.io/s/mutable-surf-nynlx
이제 setState
.
나는 이것이 누군가에게 도움이되기를 바랍니다!
답변
useEffect
특정 소품이나 상태에 연결할 수 있습니다. 따라서 무한 루프 훅을 피하기 위해해야 할 일은 어떤 변수 나 상태를 바인딩하는 것입니다.
예를 들면 :
useEffect(myeffectCallback, [])
위의 효과는 구성 요소가 렌더링 된 후에 만 발생합니다. 이것은 componentDidMount
수명주기 와 유사합니다.
const [something, setSomething] = withState(0)
const [myState, setMyState] = withState(0)
useEffect(() => {
setSomething(0)
}, myState)
위의 효과는 내 상태가 변경된 경우에만 componentDidUpdate
발생합니다. 이것은 모든 변경 상태가 발생하는 것은 아니라는 점 을 제외하고 는 비슷 합니다.
이 링크를 통해 자세한 내용을 읽을 수 있습니다.
답변
▶ 1. useEffect 후크 내부에 상태를 설정할 수 있나요?
원칙적으로 내부 useEffect
및 렌더링 중을 포함하여 필요한 곳에 상태를 자유롭게 설정할 수 있습니다 . 후크를 deps
적절하게 설정하거나 조건부로 상태 를 설정하여 무한 루프를 피하십시오 .
▶ 2. 다른 상태에 의존하는 상태가 있다고 가정 해 보겠습니다. A를 관찰하고 useEffect 후크 내부에 B를 설정하는 후크를 만드는 것이 적절합니까?
다음에 대한 고전적인 사용 사례를 설명 했습니다 useReducer
.
useReducer
일반적으로 여러 하위 값 을 포함 하는 복잡한 상태 논리가 있거나 다음 상태가 이전 상태에 의존 하는useState
경우 보다 선호됩니다 . ( React 문서 )상태 변수 설정 이 다른 상태 변수 의 현재 값에 따라 달라지는 경우 둘 다로 대체 할 수 있습니다 . […] 글을 쓰는 자신을 발견하면 대신 감속기를 사용하는 것을 고려하는 것이 좋습니다. (
useReducer
setSomething(something => ...)
Dan Abramov, Overreacted 블로그 )
▶ 3. 버튼을 클릭하면 첫 번째 효과가 실행되어 다음 렌더링 전에 b가 변경되어 두 번째 효과가 실행되도록 효과가 계단식으로 표시됩니까?
useEffect
항상 렌더링이 커밋되고 DOM 변경 사항이 적용된 후에 실행 됩니다. 첫 번째 효과가 발생하고 변경 b
되고 다시 렌더링됩니다. 이 렌더가 완료된 후 두 번째 효과는b
변경 사항 됩니다.
▶ 4. 이와 같이 코드를 구조화하면 성능상의 단점이 있습니까?
예. 상태 변경을 래핑하여 b
분리에 useEffect
대한 a
이러한 영향은 잠재적으로 사용자가 볼 수있다 – 브라우저는 추가적인 레이아웃 / 페인트 위상을 갖는다. useReducer
시도해 보고 싶은 방법이 없다면 직접 b
상태를 변경할 수 있습니다 a
.