반응 후크: useState
오늘은 동일한 카운터 구성 요소의 두 버전을 비교하여
useState
후크를 살펴보겠습니다. 그 중 하나는 클래스 구문을 사용하여 작성되고 다른 하나는 후크를 사용하여 작성됩니다.카운터(클래스): https://codepen.io/alveem/pen/VwayxYx
카운터(후크): https://codepen.io/alveem/pen/OJNzvqa
소개
클래스 기반 카운터의 코드는 다음과 같습니다.
class Counter extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0
}
}
increase = () => {
this.setState({ count: this.state.count + 1 })
}
decrease = () => {
this.setState({ count: this.state.count - 1 })
}
reset = () => this.setState({ count: 0 })
render() {
return (
<div className="counter">
<p className="count">{this.state.count}</p>
<div className="controls">
<button onClick={this.increase}>Increase</button>
<button onClick={this.decrease}>Decrease</button>
<button onClick={this.reset}>Reset</button>
</div>
</div>
);
}
}
useState
버전은 다음과 같습니다.const Counter = () => {
const [count, setCount] = React.useState(0);
const increase = () => setCount(count + 1);
const decrease = () => setCount(count - 1);
const reset = () => setCount(0);
return (
<div className="counter">
<p className="count">{count}</p>
<div className="controls">
<button onClick={increase}>Increase</button>
<button onClick={decrease}>Decrease</button>
<button onClick={reset}>Reset</button>
</div>
</div>
)
}
useState
메서드는 초기 상태 값을 받아 첫 번째 요소가 상태에 대한 참조이고 두 번째 요소가 상태를 변경하는 함수인 배열을 반환합니다.코드를 더 깔끔하게 만들기 위해 배열을 분해하고 있습니다. 다음과 동일합니다.
const countStateArray = React.useState(0);
const count = countStateArray[0];
const setCount = countStateArray[1];
비동기성
상태 변경의 비동기 동작이 후크의 영향을 받는지 살펴보겠습니다.
클래스 컴포넌트
지금
2
대신 1
만큼 카운터를 늘리고 싶습니다. this.setState
메서드에 다른 increase
문을 추가해 보겠습니다.increase = () => {
this.setState({ count: this.state.count + 1 })
this.setState({ count: this.state.count + 1 })
}
그러나 카운터는
1
가 비동기이기 때문에 여전히 setState
만큼만 증가합니다. setState
는 Object.assign
를 사용하여 상태 업데이트를 할당하므로 다음과 같이 끝납니다.Object.assign(
this.state, // current state { count: 0 }
{ count: 1 }, // first state update
{ count: 1 }, // second state update
)
일치하는 키가 전달된 마지막 개체
Object.assign
는 원래 개체의 값을 업데이트하는 데 사용됩니다.대신
setState
에 함수를 전달해 보겠습니다.increase = () => {
this.setState(state => ({ count: state.count + 1 }))
this.setState(state => ({ count: state.count + 1 }))
}
이제 카운터가
2
만큼 증가합니다.기능성 성분
이제
useState
를 사용하여 동일한 작업을 수행하려고 합니다. setCount
메서드 내에서 두 번째로 increase
를 호출합니다.const increase = () => {
setCount(count + 1)
setCount(count + 1)
}
그리고 카운터는
1
만큼만 증가합니다. 따라서 이것은 클래스 구성 요소에서 객체를 setState
에 전달했을 때와 동일한 방식으로 작동합니다.다행히도
setCount
함수는 다른 형식을 가질 수도 있습니다.const increase = () => {
setCount(prevCount => prevCount + 1)
setCount(prevCount => prevCount + 1)
}
이제 작동하며 카운터가
2
만큼 증가합니다.차이점
setState
의 동작과 useState
에 의해 반환된 setter 함수(이 예제에서는 setCount
함수)에 몇 가지 차이점이 있습니다.소품 받기
setState
메서드는 전달된 콜백 함수의 두 번째 인수로 props를 전달합니다.this.setState((state, props) => console.log(props))
상태 업데이트 동작
위에서 언급한 대로
setState
는 객체를 병합하여 상태를 업데이트합니다. 후크는 전체 상태를 대체합니다.카운터의
decrease
메서드를 제한하여 0
아래로 내려가지 않도록 합시다.클래스 구성 요소(setState)
다음은 메서드가 클래스 구성 요소에서 보이는 것입니다.
decrease = () => {
this.setState(prevState => {
if (prevState.count <= 0) return;
this.setState({ count: prevState.count - 1})
})
}
3행에서는 아무 것도 반환하지 않습니다. React가 이전 상태를 반환된 것과 병합하기 때문에 상태는 여전히 업데이트됩니다.
기능 구성 요소(useState)
기능적 구성 요소에서 유사한 작업을 수행하면 어떻게 됩니까?
const decrease = () => setCount(prevCount => {
if (prevCount <= 0) return;
return prevCount - 1;
})
카운터가
0
에 있을 때 이를 줄이려고 하면 숫자가 사라집니다.undefined
에 전달된 콜백 함수에서 반환하는 모든 것이 새 상태로 설정되기 때문에 새 상태는 setCount
로 설정됩니다. 그리고 카운터를 높이려고 하면 NaN
가 됩니다.대신 새 값이
setState
에서처럼 자동으로 병합되지 않기 때문에 전체 새 상태를 반환해야 합니다.const decrease = () => setCount(prevCount => {
if (prevCount <= 0) return 0;
return prevCount - 1;
})
이제 예상대로 작동합니다.
useState
에서 여러 값이 있는 개체를 사용하는 경우 새 키-값 쌍과 함께 이전 키-값 쌍을 포함하는 새 개체를 전달해야 합니다.복잡한 상태를 관리하려면 Hooks docs에서
useReducer
를 사용하는 것이 좋습니다.추가 자료
useState
? Rules of Hooks (문서에서)
Reference
이 문제에 관하여(반응 후크: useState), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/alveem/react-hooks-usestate-1i6g텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)