📌 React의 상태관리는 어떻게 진행되고 있었나?
React 에서 서로 다른 component를 연결하는 방법은 props drilling 이다 .
top레벨의 components에서 bottom레벨의 components 에겟 속성을 전달해야 한다.
< 실제 TodoList 프로젝트 당시 props drilling 상황
Atomic design 패턴을 고려하여 만든 프로젝트를 진행할 당시
* TodoList Column을 누르면 popup이 나오고
* 그 안 (의안의안)의 Buton을 누르면 popup이 닫히는 동작을 작동시킬때
popup state를 끌고끌고 들어가야 했다...
이걸 해결하기 위해서는⭐️ global state가 모든 components에게 존재해야 한다.
그 깊이가 깊든 관계가 복잡하든 간에 말이다. 이런 문제를 해결하기 위해 나온것이 Redux 빠밤.
📌 Redux의 등장
React의 상태관리 라이브러리
Redux는 상태변화 로직이 들어있는 스토어를 통해 원하는 component에 state와 함수를 직접 주입한다.
Redux의 사용을 위해 필요한 funciton들 : actions, reducers, store...
REact application의 상태관리가 좀더 용이하지만,
리덕스를 사용하기 위해선 무거운코드와 복잡한 환경이 조성된다.
⚠️ 이와 다르게 useContextd API 나 React Hooks는 그렇지 않다.
라이브러리, 폴더 다운로드가 불필요하고 좀더 직접적으로 global state를 관리할 수 있다.
📌 Context API
React Context는 React 16.3 부터 React components 에서 global함을 가질 수 있게 되었다.
React 공식문서
"Context는 props는 단계별로 전달하는 과정 없이 component에게 data 를 전달한다 "
context 사용법
import React from 'react';
const newContext = React.createContext({ color: 'black' });
const { Provider, Consumer } = newContext;
<Provider value={color: 'blue'}>
{children}
</Provider>
<Consumer>
{value => <span>{value}</span>}}
</Consumer>
newContext 는 Provider과 Consumer을 객체로 반환한다.
Provider component
component의 깊이와 계층에 관계없이 모든 자식 component의 state를 만들 수 있다.
Consumer component
Provider에게서 받은 data를 props drilling없이 소비한다.
📌React Hooks
React Hooks 은 기존의 class 기반의 component환경인 React에서 class 가 아닌
functional component환경을 만들고 함수 기반의 상태(state)관리를 가능하게 한다. 즉 함수형 프로그래밍이 가능하게 만들어줌
원래 Context API를 사용하려면 내용들을 다
Consumer안에 감싸고 state 접근 시 함수를 거쳐야 했다.{value => <span>{value}</span>}}
useContext
useContext에서는 state에 접근하기 위해 context를 만든다
const newContext = React.createContext({ color: 'black' });
const value = useContext(newContext);
console.log(value); // this will return { color: 'black' }
useContext를 사용하여 state접근시 Consumer로 감싸지 않고도 쉽게 state에 접근 가능해졌다. => value 만 있으면 됨! 😆
useReducer
useReducer은 React 16.8에서 등장했는데 JS의 reduce함수와 같달까?
useReducer은 reducer function , initial state 값을 받아 => new state를 반환
reducer funciton | => new state |
initial state |
const [state, dispatch] = useReducer((state, action) => {
const { type } = action;
switch(action) {
case 'action description':
const newState = // do something with the action
return newState;
default:
throw new Error()
}
}, []);
dispath 함수 => useReducer가 action을 보고 그 type에 맞는 action을 실행한다.
Context API + useReducer
지금까지는 ContextAPI와 uesReducer의 활용을 각각 보았는데,
이제 둘을 결합하여 React의 global state를 관리해 보자 => store.js 라는 파일을 만들어서 관리 할 거!
// store.js
import React, {createContext, useReducer} from 'react';
const initialState = {};
const store = createContext(initialState);
const { Provider } = store;
const StateProvider = ( { children } ) => {
const [state, dispatch] = useReducer((state, action) => {
switch(action.type) {
case 'action description':
const newState = // do something with the action
return newState;
default:
throw new Error();
};
}, initialState);
return <Provider value={{ state, dispatch }}>{children}</Provider>;
};
처음 ContexAPI를 생성할때
createContesst는 { Provider, Consumer} (state생성 , state 소비)를 만들었지만
여기서는 Provider만받아 state를 생성하고 useContext를 이용하여 소비할 것 !
state 생성 | State 소비 | |
ContextAPI | Provider | Consumer |
Context API + useReducer | Provider | useContext로 소비 ( useReducer을 활용한 ) |
이로써 dispatch 함수를 이용하여 state를 관리한다!
<dispatch 사용 예시 >
<button onClick = { () => dispatch( { type: " action description" ,}) } >
단!! 여기서 사용할 state 를 global하게 관리하고 싶다면 App을 감싸줘야 한다.
<index.js >
// root index.js file
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import { StateProvider } from './store.js';
const app = (
<StateProvider>
<App />
</StateProvider>
);
ReactDOM.render(app, document.getElementById('root'));
<Component> 사용 시
// exampleComponent.js
import React, { useContext } from 'react';
import { store } from './store.js';
const ExampleComponent = () => {
const globalState = useContext(store);
console.log(globalState); // this will return { color: red }
};
이제 useContext를 import하여 context가 어떤 component에도 접근이 가능하다
참고:blog.logrocket.com/use-hooks-and-context-not-react-and-redux/
'📗 React' 카테고리의 다른 글
textarea 줄 수에 따라 style 변경하기 ( line count에 따른 border radius설정 및 textarea line count 개수를 이용한 CSS 설정 ) (0) | 2022.04.25 |
---|---|
[React] OAuth Github 로그인 구현하기 (2) | 2021.06.05 |
[React] json-server에서 axios 로 데이터 불러오기 (0) | 2021.04.12 |
[React] CRA로 프로젝트 초기 세팅 (0) | 2021.04.11 |
[React] React 의 특징, JSX 이해하기 (0) | 2021.04.11 |
댓글