[TIL] Redux3. React-Redux 사용법.

2022. 10. 18. 20:52React/Redux

이 시리즈는 노마드 코더님의 "초보자를 위한 리덕스 101"을 보고 배운 내용을 정리합니다.

비약이나 틀린 내용이 있다면 언제든 댓글로 알려주세요..! (매우 환영입니다😀)

 


🎛️ TO-DO Apps

 

저번이랑 결과물은 같지만 내용은 아예 다르다.

결론적으로 말하면 React에서는 dispatch와 subscribe 함수를 props로 받아와야 한다는 것!

TypeScript에서 쓸 생각하니까 벌써 막막하다🤣

 

👜 store.js 따로 만들어주기.

React에서 ReactDOM으로 렌더링해주는 과정에서 최상단에서 store를 뿌려줘야한다.

결론적으로 파일을 따로 만들어줘야한단 소리!

 

store.js

import { legacy_createStore } from "redux";

const ADD = 0;
const DELETE = 1;

const addToDo = (text) => {
    return {
        type: ADD,
        text
    };
};

const deleteToDo = (id) => {
    return {
        type: DELETE,
        id
    };
};

const reducer = (state = [], action) => {
    switch (action.type) {
        case ADD:
            return [{ text: action.text, id: Date.now() }, ...state];
        case DELETE:
            return state.filter(toDo => toDo !== action.id);
        default:
            return state;
    }
};

const store = legacy_createStore(reducer);

export const actionCreators = {
  addToDo,
  deleteToDo
}
export default store;

 

이렇게 만들어준 store는 앱의 최상단에서 Provider를 써서 뿌려준다.

이때 중요한 점은 이 store.js에서 dispatch나 subscribe를 쓰지 않는다는 점이다. 해당 컴포넌트에서 쓰지 않는 redux state를 다 받는 건 비효율적이기 때문에 사용할 컴포넌트에서 직접 getSatate(), dispatch()로 받아와야한다.

 

여담이지만, export를 저렇게 따로 빼주는 문법을 처음봤다. 굉장히 유용해보인다

(styled-component 이런데에서 쓰면 진짜 꿀이지 않을까...)

 

index.js

import React from "react";
import ReactDOM from "react-dom/client";
import App from "./components/App";
import { Provider } from "react-redux";
import store from "./store";

ReactDOM.createRoot(
    document.getElementById("root")
).render(
    <Provider store={store}>
        <App />
    </Provider>
);

 

 

🪧[중요] store와 컴포넌트의 연결, connect와 useSelector

 

강의가 2020년 기준이 마지막 업데이트여서 connect함수를 사용해서 컴포넌트와 store를 바인딩 해줬다.

요즘에는 따로 hooks로 정의된 useSelector를 사용해서 state를 가져온다고 한다.

 

1. connect로 store 접근

/**
*@toDos: getCurrentState로 받아온 현재 redux state
*@addToDo: dispatch로 묶어준 addToDo 함수
*/

const Home = ({ toDos, addToDo }) => {
//...

function getCurrentState(state) {
  return { toDos: state }
}

function mapDispatchToProps(dispatch) {
  return {
    addToDo: (text) => dispatch(actionCreators.addToDo(text))
  };
}

export default connect(getCurrentState, mapDispatchToProps)(Home);

 

redux 배우면서 가장 충격인 점이 두 가지가 있었다.

먼저 첫 번째로 저 connect 문법이다.

 

 

저런 식의 표기 방법을 currying이라고 한다. 진짜 처음들었다.

함수의 인자로 또 함수를 넣는 경우, (인간 친화적인 이유라고 한다.) 그냥 여러개를 늘여쓰는게 아니라 괄호를 인자별로 나눠서 넣을 수 있는 기법이다.

 

https://javascript.info/currying-partials

 

Currying

 

javascript.info

 

두 번째는 getState()랑 dispatch()해줄 함수가 props에서 들어온다는 거..

이런 생각을 어떻게 하셨을까? return하는 값은 object 형태로 담아서 원하는 키 이름을 넣어주도록 하자.

 

2. useSelector로 store 접근

const Home = ({ toDos, addToDo }) => {
  const todo = useSelector((state) => {...})
  }

 

만약에 useSelector hooks로 제어하고 싶으면 첫 번째 인자에 넣을 함수에서 state를 받아서 사용할 수 있으니 이런 식으로 컴포넌트 최상단에서 정의하고 쓰면 된다.


여러모로 React랑 redux를 같이 쓰니 왜 유용한지 감이 잘온다. 특히 코드가 너무 직관적이어서 이해가 쉽다.

다만, store에 하나의 state만 저장할 수 있는 데에서 뭔가 더 다른 라이브러리가 있고 타고타고 깊은 곳으로 내려가야하지 않을까 싶다