React 관련 자료를 살펴보다가 Derived State라는 것에 대해 알게 되었고 이를 지양해야 한다고 알게되었습니다.
Derived State가 무엇이고 해결은 어떤 방식으로 하는지 알아보려 합니다.
Derived State는 props로 전달받은 정보가 컴포넌트에서 state로서 정의되어 관리되는 것을 의미합니다.
derived는 ~파생된, ~유래된 이라는 뜻을 가진 영단어 입니다.
예시를 살펴보겠습니다.
import { useState } from 'react';
import './App.css';
import DerivedState from './DerivedState';
function DerivedState({ defaultEmail, onChange }) {
const [value, setValue] = useState(defaultEmail);
const handleChange = (event) => {
setValue( event.target.value );
};
return (
<form>
<input onChange={handleChange} value={value} />
</form>
);
};
function App() {
const [state, setState] = useState({ email: "test", id: '123123' })
return (
<div className="App">
<DerivedState defaultEmail={state.email} />
<button onClick={() => setState({...state, email: 'example'})}>setEmail example</button>
</div>
);
}
export default App;
위의 예제에서 button을 아무리 눌러도 input내의 값은 변화하지 않습니다.
input 내의 value 값은 DerivedState 컴포넌트 내에서 관리되는 state이기 때문입니다.
분명 부모 컴포넌트에서 defaultEmail props로 넘겨주었지만 부모 컴포넌트의 state를 변경해주어도 자식 컴포넌트 내부에서의 값은 변경되지 않습니다.
위의 상황은 분명히 이상합니다!!
코드의 흐름과 실제 동작이 일치하지 않는 것만 같습니다
이렇게 간단한 코드에서도 위와 같이 동작이 흐름대로 수행되지 않는다면 이는 분명 좋지 않습니다.
공식문서에서는 두개의 방법을 안내하고 있습니다.
1. 제어 컴포넌트로 만들기
2. 비제어 컴포넌트로 만들기
제어/비제어 컴포넌트에 관해서는 제가 이전에 포스팅 해놓은 글을 걸어두겠습니다.
2022.03.03 - [Frontend/React] - 제어 컴포넌트 vs 비제어 컴포넌트
1. 제어 컴포넌트로 만들기
import { useState } from "react";
function DerivedState({ email, onChange }) {
return (
<form>
<input onChange={(e) => onChange(e.target.value)} value={email} />
</form>
);
}
function App() {
const [email, setEmail] = useState("test");
return (
<div className="App">
<DerivedState email={email} onChange={setEmail} />
{email}
</div>
);
}
export default App;
위와 같이 변경하면 DerivedState는 제어 컴포넌트가 됩니다.
DerivedState 컴포넌트는 props로 전달받은 정보들을 redering만 시켜줄 뿐입니다.
모든 상태관리 로직은 부모 컴포넌트에서 정의됩니다.
2. 비제어 컴포넌트로 만들기
비제어 컴포넌트로 적용한 코드입니다.
자식 컴포넌트에서 props를 자신의 state로 정의하여 사용하지만
부모 컴포넌트에서 다른 인스턴스를 선택했을때 input의 값은 초기화 됩니다.
DerivedState는 초깃값을 정의하는데에만 사용됩니다.
또한 부모컴포넌트에서 key값을 같이 전달해줍니다.
React에서 key값은 형제 컴포넌트간에 불필요한 렌더링을 방지하기 위해 사용되어 집니다.
형제 컴포넌트간에만 고유한 값을 가지고 있으면 값이 변경되었을때 React에서 전체를 rendering 하는 것이 아닌 key값이 변경된 데이터만 렌더링 시킵니다.
key 관련해서는 따로 포스팅 예정입니다.
Derived State에 대한 개념을 알고 피하여 맨 위의 bad example과 같은 경우를 피하는 것이 좋을것 같습니다.
출처 : https://ko.reactjs.org/docs/react-component.html#static-getderivedstatefromprops
React.Component – React
A JavaScript library for building user interfaces
ko.reactjs.org
https://ko.reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html
You Probably Don't Need Derived State – React Blog
React 16.4 included a bugfix for getDerivedStateFromProps which caused some existing bugs in React components to reproduce more consistently. If this release exposed a case where your application was using an anti-pattern and didn’t work properly after t
ko.reactjs.org
https://reactiver.dev/review-react-derived-state/
React Derived State 다시 보기
Derived State가 뭔지 이해하고, 올바른 컴포넌트 디자인 패턴에 대해 알아보자.
reactiver.dev
'Frontend > React' 카테고리의 다른 글
React input onFocus, onBlur(focus out) 😶🌫️ (0) | 2022.04.02 |
---|---|
React moment locale 적용하기 🌹 (1) | 2022.04.02 |
React props, state 🏔 (0) | 2022.04.02 |
React useReducer 🌱 (0) | 2022.04.02 |
React typescript 에서 dataset 이용하기 😢 (0) | 2022.04.01 |