여러 Component에서 state를 공유해야 하는 경우가 있다.
이럴 경우 해결법은 공유해야 하는 state 처리를 공통 부모에서 하는 것이다.
미리보는 결과
예시로 다음과 같은 간단한 예시를 구현한다고 해보자.
요구사항
- 'IncreaseValue' 버튼을 누르면 value 값이 증가해야 한다.
- 'DecreaseValue' 버튼을 누르면 value 값이 감소해야 한다.
- 그리고 'current value : '에 현재 값을 표시해야 한다.
- IncreaseValule, DecreaseValue, current value 모두 개별적인 Component로 만들어야 한다!!
핵심은 마지막 줄이다.
value 값이 state가 되어 값이 바뀔때마다 re-render를 해줘야 하는데, 두 개의 버튼 컴포넌트에서 state 값을 수정해주어야 한다.
그리고 해결 방법은 맨 앞에 설명한 그대로이다.
구현
폴더 구조를 간략하게 나타내면 다음과 같다.
src
├──App.tsx
└──components
├──IncreaseComponent.tsx
├──DecreaseComponent.tsx
└──ValueComponent.tsx
먼저 루트인 App.tsx부터 살펴보자.
// App.tsx
import IncreaseComponent from './components/IncreaseComponent';
import DecreaseComponent from './components/DecreaseComponent';
import ValueComponent from './components/ValueComponent';
import { useState } from 'react';
function App() {
const [value, setValue] = useState(0);
const style = { width: '200px', margin: 'auto', marginTop: '20px' };
return (
<div style={style}>
<IncreaseComponent value={value} setValue={(val) => setValue(val)} />
<DecreaseComponent value={value} setValue={(val) => setValue(val)} />
<ValueComponent value={value} />
</div>
);
}
export default App;
value 값에 따른 렌더링을 위해 useState를 사용하였고, 3개의 자식 컴포넌트에 state와 setter를 사용할 수 있는 콜백을 넘겨준다.
이렇게 state와 setter를 간접적으로 넘겨줌으로서 자식 컴포넌트 내에서 간접적으로 부모의 state를 변경하고, 렌더를 다시 실행할 수 있도록 하는 것이 핵심이다.
그 다음으로 자식 컴포넌트를 살펴보자.
// IncreaseComponent.tsx
interface Props {
value: number;
setValue: (val: number) => void;
}
export default function IncreaseComponent(props: Props) {
return (
<div>
<button onClick={() => props.setValue(props.value + 1)}>
IncreaseValue
</button>
</div>
);
}
IncreaseComponent에서는 value를 1 증가시켜야 한다.
따라서 props로 value 값과 그의 setter를 전달받았고, 버튼의 onClick handler에서 전달받은 setter를 호출해 사용하였다.
DecreaseComponent 또한 완전히 같은 구조이다.
// DecreaseComponent.tsx
interface Props {
value: number;
setValue: (val: number) => void;
}
export default function DecreaseComponent(props: Props) {
return (
<div>
<button onClick={() => props.setValue(props.value - 1)}>
DecreaseValue
</button>
</div>
);
}
ValueComponent에서는 value 값을 실시간으로 보여주기만 하면 된다.
// ValueComponent.tsx
interface Props {
value: number;
}
export default function ValueComponent(props: Props) {
return <div>{`current value : ${props.value}`}</div>;
}
이제 이를 실행해보면 가장 앞에서 보여준 결과 화면이 나오게 된다.
PS. 왜 항상 과제 테스트처럼 중요한 때에는 이런게 생각이 나지 않을까...
'Web development > React' 카테고리의 다른 글
React에서 Modal 관리하기 (0) | 2024.03.19 |
---|