[React] 상태관리 Redux / ContextAPI

Redux가 좋은점?

👍🏻 props 전송 과정 없이 모든 컴포넌트가 state에 접근하여 사용할 수 있다!
👍🏻 상태관리에 유용

설치

npm install react-router-dom
npm install redux react-redux

기본 세팅

  • index.js
import { BrowserRouter } from 'react-router-dom';
import {Provider} from 'react-redux';
import {createStore} from 'redux';

const reduxState = 100;
function reducer(state = reduxState, action){
  return state
}
let store = createStore(reducer)

ReactDOM.render(
  <BrowserRouter>
    <Provider store={store}>
      <Redux />
    </Provider>
  </BrowserRouter>,
  document.getElementById('root')
);

👍🏻 Provider에서 넘겨준 state는 <Redux /> 뿐 아니라 다른 여러개의 컴포넌트에서도 꺼내 사용할 수 있다!

👍 Component에서 state 사용 방법

useSelector, useDispatch 등 편한 훅스가 있어서 connect함수를 많이쓰진 않는다

useSelector

  • Redux.js
import React from 'react'; 
import {useSelector} from 'react-redux';

function Redux(){

    const gotReduxState = useSelector( (state) => state);

    return(
        <div>
             받아온 redux state : {gotReduxState} (useSelector)
        </div>
    )
}

export default Redux;

connect

  • Redux.js
import React from 'react'; 

function Redux(props){
    return (
        <div>
        	받아온 redux state : {props.gotReduxState} (connect)
        </div>
    )
}

function stateToProps(props){ 
    return {
        gotReduxState : props
    }
}

export default connect(stateToProps)(Redux);

결과는 같다! (소스코드)

👍 상태관리

reducer action

//index.js
const reduxState = 100;
function reducer(state = reduxState, action){
  if (action.type === "plus"){
    state++;
    return state 
  }
  else{
    return state
  }
}
let store = createStore(reducer);

reducer dispatch

//Redux.js
function Redux(){
    const gotReduxState = useSelector( (state) => state);
    const dispatch = useDispatch();
    return(
        <div>
            <button onClick={()=>{ dispatch( {type:'plus'} ) }}> PLUS </button>
        </div>
    )
}

export default Redux;

여러개의 reducer

🌟 store는 하나여야 한다 !!
reducer가 여러개라면 ? combineReducers!

// index.js
const reduxState = 100;
function reducer(state = reduxState, action){
  if (action.type === "plus"){
    state++;
    return state 
  } else{
    return state
  }
}

const reduxState2 = 200;
function reducer2(state = reduxState2, action){
  if (action.type === "plus"){
    state++;
    return state 
  } else{
    return state
  }
}

let store = createStore(combineReducers({reducer, reducer2}));
//Redux.js
const gotReduxState = useSelector( (state) => state.reducer);

useSelector 인자는 콜백함수
그 콜백함수의 인자로 state가 전부 포함된 객체, 즉 index.js에서 Provider로 넘겨준 store의 reducer의 state객체(값)

const gotReduxState = useSelector( (state) => console.log(state));

여러개의 reducer를 combine해서 사용한 경우 사용할 state객체를 지정해주어야 한다!

    const gotReduxState = useSelector( (state) => state.reducer);

useReducer

🤔 useDispatch 는 Store의 기능인 dispatch를 함수에서 사용 가능하게 해주는 hook 입니다.
마찬가지로 (reducer,초기상태)를 인자로 받는 훅스가 useReducer
const [state, dispatch] = useReducer(reducer, initialState);
여러 컴포넌트에 걸쳐 사용되고 수정되는 state라면 useState 대신 사용할 수 있음.

// Redux.js에서
import child from './Child'
< Child />
//Child.js
import React, {useReducer} from 'react'; 

const initialState = {
    inputs: {
      value: 'InitialStateValue',
    }
}
function reducer(state, action) {
    if (action.type === 'change'){
        return {
            ...state,
            inputs: {
              ...state.inputs,
              value: action.payload
            }
          };
    }
    return state;
  }
  
function UseReducer(){
    const [state, dispatch] = useReducer(reducer, initialState);
    return(
        <div>
            UseReducer.js에서 {state.inputs.value}
            <button onClick={()=>{ dispatch( {type:'change', payload:'NewStateValue'} ) }}> CHANGE </button>
        </div>
    )
}

export default UseReducer;

좋은 웹페이지 즐겨찾기