React useState() - #Part_2

art11010·2022년 6월 22일
0

React

목록 보기
13/24

비동기로 실행되는 setState()

여러 번 연속해서 setState()를 호출 한다면 단일 업데이트로 한 번에 처리한다.

비동기 처리 문제점

아래 코드에서 multiplyAdd() 를 실행시켜 버튼을 클릭한다 가정했을 때
multiply() 이후 add() 가 실행되어 output : 1 → 3 → 7 → 15로 값이 반환될거라 생각할 것이다.
하지만 실제로 버튼을 클릭했을 때 반환된 값은 output : 1 → 2 → 3 → 4이며 multiply() 가 실행되지 않는다는 것을 확인할 수 있다.

const [number, setNumber] = useState(1);

const add = () => setNumber(number + 1);
const multiply= () => setNumber(number * 2);
const multiplyAdd = () => {
	// 연속해서 setState()를 호출
	multiply();	// number * 2
	add();		// number + 1
};
return (
	<>
		<button onClick={multiplyAdd}>{number}</button>
		// output : 1 → 2 → 3 → 4
	</>
);

이는 여러 번 연속해서 setState()를 호출할 때 React는 제공한 객체를 현재 state로 병합하기 때문이다.

multiplyAdd() 가 실행되었을 때 스탭 마다 값이 달라져야하는 number의 값을 한 번에 병합시켜 실행시키기 때문에 마지막 값이 number에 덮어져 number + 1을 반환하는 것이다.

// 이런 식으로 병합되어 실행됨
Object.assign({ number, number: number * 2, number : number + 1 })
/* ↑ 사실상 다를 게 없다. ↓ */
Object.assign({ number, number : number + 1 })

해결 방안

현재의 State가 인자인 함수를 넘겨 업데이트 된 값으로 동작하게 처리한다.

const [number, setNumber] = useState(1);

const add = () => setNumber((number) => number + 1);
const multiply = () => setNumber((number) => number * 2);
const multiplyAdd = () => {
	// 연속해서 setState()를 호출
	multiply();	// number * 2
	add();		// number + 1
};
return (
	<>
		<button onClick={multiplyAdd}>{number}</button>
		// output : 1 → 3 → 7 → 15
	</>
);

단방향 데이터 흐름

컴포넌트는 자신의 state를 자식 컴포넌트에 props로 전달할 수 있다.

export default function ParentCompnt() 
	return (
		<ChildrenCompnt date={this.state.date} />
	)
}

ChildrenCompnt 컴포넌트는 date를 자신의 props로 받으며,
props로 받은 date가 ParentCompnt의 state로부터 왔는지, ParentCompnt의 props에서 왔는지, 수동으로 입력한 것인지 알지 못한다.

일반적으로 이를 '하향식(top-down)' 또는 '단방향식' 데이터 흐름이라고 하며,
모든 state는 항상 특정한 컴포넌트가 소유하고 있으며 그 state로부터 파생된 UI 또는 데이터는 오직 트리구조에서 자신의 “아래”에 있는 컴포넌트에만 영향을 미친다.

State 끌어올리기

export default function A() 
	return (
		<>
			<B />	// have state
			<C />	// need state
  		</>
	)
}

A 라는 부모 컴포넌트가 있고 같은 레벨의 자식 컴포넌트 B, C 가 있다.
B 컴포넌트에는 내부적으로 관리하는 state가 있다.
이때 B 컴포넌트의 state를 C 컴포넌트가 필요한 상황이라 가정한다면
B 컴포넌트의 state를 C 컴포넌트에 그대로 가져오는 것이 아닌
B 컴포넌트의 state를 A 컴포넌트에 위치해 올림으로써 A 컴포넌트가 가진 state를 B와 C 컴포넌트에 Props로 받도록 하는 것이 State 끌어올리기다.

State 끌어올리기를 통해 데이터를 한 곳에서 관리 및 편집할 수 있도록 하며,
React 지향하는 '하향식(top-down)' 데이터 흐름을 가질 수 있다.

profile
미래의 나를 위해 쓰는 velog💡

0개의 댓글