useEffect 후크 내부의 상태를 설정할 수 있습니까?
다른 상태에 의존하는 상태가 있다고 합시다(예를 들어 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>
)
}
이렇게 요.setState
에 inside inside inside useEffect
무한 루프가 생성됩니다.이러한 루프는 아마 일으키고 싶지 않을 것입니다.그 규칙에는 몇 가지 예외가 있는데 나중에 이야기하겠습니다.
useEffect
마다, 렌더링할 때, 렌더링할 때 .setState
에서 사용하면 되고 컴포넌트가 됩니다.useEffect
기타 등등.
중 죠.useState
의 of의 useEffect
않습니다.는 빈 을 두 번째 입니다.useEffect
useEffect(() => {....}, [])
, 이펙트 1회 첫 마운트만.마운트 함수 에, 「마운트/마운트 함수」가 됩니다.이 기능은 구성 요소에서 데이터 가져오기를 수행할 때 구성 요소 상태에 요청 데이터를 저장하려는 경우 널리 사용됩니다.
이것은 장래의 목적을 위해서도 도움이 될 수 있습니다.
setState에서 를 사용해도 useEffect
루프를 만들지 않으려면 이미 설명한 대로 주의를 기울이면 됩니다.
그러나 발생할 수 있는 문제는 이것뿐만이 아닙니다.아래를 참조해 주세요.
구성 상상해보세요.Comp
를 수신한다.props
로부터 A에 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
.
이게 누군가에게 도움이 됐으면 좋겠어!
한 이펙트 내에서 setState를 실행해도 이펙트는 항상 렌더링 단계가 완료된 후에 실행됩니다.다른 이펙트는 갱신된 상태를 읽어내고 렌더링 단계 후에만 이펙트에 액션을 수행합니다.
것이 좋을지도 , 만약 이 두 가지 행동을 같이 할 이 없다면b
수 changing a
하는 것이 .
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
보통보다 낫다useState
복수의 서브값을 수반하는 복잡한 스테이트 로직이 있는 경우, 또는 다음의 스테이트가 앞의 것에 의존하는 경우. (React docs)상태 변수 설정이 다른 상태 변수의 현재 값에 따라 달라지는 경우 두 변수 모두를 다음과 같이 바꿀 수 있습니다.
useReducer
[...] 글을 쓰고 있는 자신을 발견했을 때setSomething(something => ...)
대신 리덕터 사용을 검토하는 것이 좋습니다.(Dan Abramov, 과잉반응 블로그)
let MyComponent = () => {
let [state, dispatch] = useReducer(reducer, { a: 1, b: 2 });
useEffect(() => {
console.log("Some effect with B");
}, [state.b]);
return (
<div>
<p>A: {state.a}, B: {state.b}</p>
<button onClick={() => dispatch({ type: "SET_A", payload: 5 })}>
Set A to 5 and Check B
</button>
<button onClick={() => dispatch({ type: "INCREMENT_B" })}>
Increment B
</button>
</div>
);
};
// B depends on A. If B >= A, then reset B to 1.
function reducer(state, { type, payload }) {
const someCondition = state.b >= state.a;
if (type === "SET_A")
return someCondition ? { a: payload, b: 1 } : { ...state, a: payload };
else if (type === "INCREMENT_B") return { ...state, b: state.b + 1 };
return state;
}
ReactDOM.render(<MyComponent />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.0/umd/react.production.min.js" integrity="sha256-32Gmw5rBDXyMjg/73FgpukoTZdMrxuYW7tj8adbN8z4=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.0/umd/react-dom.production.min.js" integrity="sha256-bjQ42ac3EN0GqK40pC9gGi/YixvKyZ24qMP/9HiGW7w=" crossorigin="anonymous"></script>
<div id="root"></div>
<script>var { useReducer, useEffect } = React</script>
▶ 3. 다음 렌더링 전에 버튼을 클릭했을 때 첫 번째 효과가 발생하여 b가 변화하고 두 번째 효과가 발생할 수 있습니까?
useEffect
렌더가 커밋되고 DOM 변경 내용이 적용된 후에는 항상 실행됩니다.첫 번째 효과는 발화, 변화b
재연결을 일으킵니다.되면 두 됩니다.b
★★★★★★★★★★★★★★★★★★.
let MyComponent = props => {
console.log("render");
let [a, setA] = useState(1);
let [b, setB] = useState(2);
let isFirstRender = useRef(true);
useEffect(() => {
console.log("useEffect a, value:", a);
if (isFirstRender.current) isFirstRender.current = false;
else setB(3);
return () => {
console.log("unmount useEffect a, value:", a);
};
}, [a]);
useEffect(() => {
console.log("useEffect b, value:", b);
return () => {
console.log("unmount useEffect b, value:", b);
};
}, [b]);
return (
<div>
<p>a: {a}, b: {b}</p>
<button
onClick={() => {
console.log("Clicked!");
setA(5);
}}
>
click me
</button>
</div>
);
};
ReactDOM.render(<MyComponent />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.0/umd/react.production.min.js" integrity="sha256-32Gmw5rBDXyMjg/73FgpukoTZdMrxuYW7tj8adbN8z4=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.0/umd/react-dom.production.min.js" integrity="sha256-bjQ42ac3EN0GqK40pC9gGi/YixvKyZ24qMP/9HiGW7w=" crossorigin="anonymous"></script>
<div id="root"></div>
<script>var { useReducer, useEffect, useState, useRef } = React</script>
▶ 4. 이와 같은 코드 구조화에 성능 저하가 있습니까?
, ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★b
useEffect
★★★★★★에a
브라우저에는 추가 레이아웃/표시 단계가 있습니다.이러한 효과는 사용자에게 표시될 수 있습니다. 수 없으면 주라useReducer
try, change a a 、 [ a a a 、 [ ]b
말하다a
★★★★
let MyComponent = () => {
console.log("render");
let [a, setA] = useState(1);
let [b, setB] = useState(2);
useEffect(() => {
console.log("useEffect b, value:", b);
return () => {
console.log("unmount useEffect b, value:", b);
};
}, [b]);
const handleClick = () => {
console.log("Clicked!");
setA(5);
b >= 5 ? setB(1) : setB(b + 1);
};
return (
<div>
<p>
a: {a}, b: {b}
</p>
<button onClick={handleClick}>click me</button>
</div>
);
};
ReactDOM.render(<MyComponent />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.0/umd/react.production.min.js" integrity="sha256-32Gmw5rBDXyMjg/73FgpukoTZdMrxuYW7tj8adbN8z4=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.0/umd/react-dom.production.min.js" integrity="sha256-bjQ42ac3EN0GqK40pC9gGi/YixvKyZ24qMP/9HiGW7w=" crossorigin="anonymous"></script>
<div id="root"></div>
<script>var { useReducer, useEffect, useState, useRef } = React</script>
상태를 변경할 필요가 있는지 여부를 확인하는 if-statement로 setState를 랩핑해 보십시오(예일 경우 변경, 그렇지 않으면 변경).return () => {}
예.,
useEffect(() => {
if(a.currentCondition !== a.desiredCondition) {
setA();
}
return cleanup;
}, [b])
언급URL : https://stackoverflow.com/questions/53715465/can-i-set-state-inside-a-useeffect-hook
'programing' 카테고리의 다른 글
Java에서 포인터를 사용하려면 어떻게 해야 하나요? (0) | 2022.10.27 |
---|---|
PHP 배열이 연관성이 있는지 순차적인지 확인하는 방법 (0) | 2022.10.27 |
반응: 컴포넌트 함수 내에 "this"가 정의되어 있지 않습니다. (0) | 2022.10.27 |
잭슨과 롬복에게 함께 일하게 할 수 없다. (0) | 2022.10.27 |
JavaScript 개체의 내용을 인쇄하시겠습니까? (0) | 2022.10.27 |