TIL #17 Redux

Joshua Song / 송성현·2019년 12월 27일
0

이머시브_16

목록 보기
20/29

Why Use React Redux?

  • is a standalone library that can be used with any UI layer or framework (React, Angular, Vue, Ember and vanilla JS).
  • originally designed and intended for use with React. Also kept up-to-date with any API changes.
  • Encourages good React Architecture.
  • implements performance optimizations
  • Can maintain and deliver states without going through various components.
  • Can also use extra middle ware for more work.

Action

  • When a change has to be made to the state, we execute something called "Action".
 {
        type: 'INCREMENT',
        payload: number
    }


        type: 'DECREMENT'
    }

여기 예시로 만든 action 객체는 값을 더해주는 increment, 그리고 decrement라는 action 객체를 만드는 방법이다. type은 이 action종류이고 그 외의 값들은 마음대로 넣어줄 수 있다. increment같은 경우에는 payload라는 숫자를 넣어줘 추가하는 값을 정해주었다. 그리고 이 형식은 이 다음인 action Creator 와 연결되어 있다.

Action Creator

  • Action Creator is a function that makes actions. It receives a parameter and transforms it into an action object.
export const increment = (number) => {
    return {
        type: 'INCREMENT',
        payload: number
    }
}
export const decrement = () => {
    return {
        type: 'DECREMENT'
    }
}

현재 이 코드를 보면 화살표 함수로 action을 리턴한다. 화살표가 아니어도 된다.

Reducer

  • Reducer function receives two parameters and bring change / update state.
const counterReducer = (state = 0, action) => {
    switch(action.type){
        case 'INCREMENT':
            return state + action.payload
        case 'DECREMENT':
            return state -1
        default: 
            return state;
    }
}
export default counterReducer;

위 코드를 보면, 0이라는 state에 increment와 decrement action 을 적용해 increment 일 때는 payload를, decrement일때는 그냥 -1을 해준다. 가져와서 적용하는 것은 App.js 에서 해준다. action의 type을 보고 increment일때, decrement 일때를 나눠서 기능을 구현한다.

App.js

import React from 'react';
import './App.css';
import {useSelector, useDispatch} from 'react-redux';
import {increment} from './actions'
import {decrement} from './actions'

function App() {
  const counter = useSelector(state => state.counter);
  const isLogged = useSelector(state => state.isLogged); 
  const dispatch = useDispatch();
  return (
    <div className="App">
      <h1>Counter {counter}</h1>
      <button onClick={() => dispatch(increment(5))}>+</button>
      <button onClick={() => dispatch(decrement())}>-</button>
      {isLogged ? <h3>Valuable Information I shouldn't see</h3> : ""}
    </div>
  );
}

export default App;

리덕스는 한 어플당 하나의 스토어를 만다는데 스토어 안에는 현재의 앱 상태, 리듀서와 추가적으로 몇가지 내장 함수들이 있다.

위 코드를 보면 import를 통해 필요한 action creator를 가져오고 또 useSelector와 useDispatch라는 리액트 리덕스의 내장 기능들을 가져온다. Dispatch 는 액션을 파라미터로 전달한다.
useSelector는 state에 추가한 counter라는 값을 가져올 수 있게 한다. 이후 dispatch를 실행해 그 counter에 값을 수정하는 것이다.

Subscribe

  • 스토어의 내장 함수중 하나인데, 함수 형태의 값을 파라미터로 받아 전달해놓은 함수를 액션이 디스패치 될 때 마다 호출한다. 아래 코드에서는 Provider라는 모듈이 대체한다.
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import {createStore} from 'redux';
import allReducers from './reducers'
import {Provider} from 'react-redux';

const store = createStore(
    allReducers,
    window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
);

ReactDOM.render(
<Provider store={store}>
<App />
</Provider>

, document.getElementById('root'));

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();

Overview

  • State를 한 폴더에 따로 관리하고 action을 통해 state 값을 바꿔주니 편할 것 같기도 한데 그만큼 state가 늘어나고 action이 늘어나며 reducer 함수가 늘어나면 그만큼 복잡할 것 같긴 하다.
  • 시간이 난다면 react로 구현한 todoList를 redux로 리팩터 해보고 싶다. 보기 조금 더 깔끔한 것 같긴 하다. 대신 익숙해지려면 시간이 걸릴 것 같다.
profile
Grow Joshua, Grow!

0개의 댓글