React 1. Udemy(3)

khxxjxx·2021년 8월 2일
0

Udemy

목록 보기
4/9

1. Udemy(3)

Redux Toolkit

  • Redux가 공식적으로 만든 라이브러리로 Redux를 쉽게 사용할 수 있게 도와준다
  • Redux Toolkit 설치방법
✨ 새 프로젝트에서 시작하기
// Redux + Plain JS template
npx create-react-app my-app --template redux

// Redux + TypeScript template
npx create-react-app my-app --template redux-typescript

✨ 기존 프로젝트에서 시작하기
npm install || yarn add @reduxjs/toolkit

configureStore

  • createStore → configureStore
  • reducer를 전달할때는 꼭 reducer라는 property name으로 전달해야 한다
  • 슬라이스에서 리듀서 함수를 가져와서 스토어에 추가한다
    • const store = configureStore({reducer: counterSlice.reducer })
  • reducer에 object를 주어 여러 reducer를 병합할 수 있다(combineReducers 불필요)
    • const store = configureStore({reducer: {...} })

createSlice

  • reducer + action → createSlice
  • Action과 Reducer를 한번에 정의할 수 있다
  • Redux Toolkit은 immer 라이브러리를 내장하고 있어 기존 상태를 자동으로 복제하기 때문에 실수로라도 기존상태를 직접 조작할 수 없다
  • 따라서 새로운 상태객체 생성 등 모든 상태유지를 상태 값을 직접 변경하는 방식으로 코드를 작성해 재정의할 수 있다
  • 슬라이스를 생성하려면 슬라이스를 식별하기 위한 name, 초기 상태 값 initialState, 상태 업데이트 방법을 정의하는 하나 이상의 리듀서 함수가 필요하다
    • const counterSlice = createSlice({name, initialState, reducers})
  • 슬라이스가 생성되면 생성된 Redux 액션 생성자와 전체 슬라이스에 대한 리듀서 기능을 내보낼 수 있다
    • counterSlice.actions : useDispatch 훅을 이용해 dispatch할 수 있다
    • counterSlice.reducer : useSelector 훅을 이용해 저장소에서 데이터 읽을 수 있다
// 예시

// store/index.js
import { configureStore } from '@reduxjs/toolkit';
import counterReducer from './counter';
import authReducer from './auth';

const store = configureStore({
  reducer: {
    counter: counterReducer,
    auth: authReducer,
  },
});

export default store;


// index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';

import App from './App';
import store from './store/index';

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


// store/counter.js
import { createSlice } from '@reduxjs/toolkit';

const initialCounterState = { counter: 0, showCounter: true };

const counterSlice = createSlice({
  name: 'counter',
  initialState: initialCounterState,
  reducers: {
    increment(state) {
      state.counter++;
    },
    decrement(state) {
      state.counter--;
    },
    increase(state, action) {
      state.counter = state.counter + action.payload;
    },
    toggleCounter(state) {
      state.showCounter = !state.showCounter;
    },
  },
});

export const counterActions = counterSlice.actions;

export default counterSlice.reducer;


// Counter.js
import { useSelector, useDispatch } from 'react-redux';
import { counterActions } from '../store/counter';

const Counter = () => {
  const dispatch = useDispatch();
  const counter = useSelector(state => state.counter.counter);
  const show = useSelector(state => state.counter.showCounter);

  const incrementHandler = () => {
    dispatch(counterActions.increment());
  };

  const increaseHandler = () => {
    dispatch(counterActions.increase(10));
  };

  const decrementHandler = () => {
    dispatch(counterActions.decrement());
  };

  const toggleCounterHandler = () => {
    dispatch(counterActions.toggleCounter());
  };

  return (
    <div>
      <h1>Redux Counter</h1>
      {show && <div>{counter}</div>}
      <div>
        <button onClick={incrementHandler}>Increment</button>
        <button onClick={increaseHandler}>Increment by 10</button>
        <button onClick={decrementHandler}>Decrement</button>
      </div>
      <button onClick={toggleCounterHandler}>Toggle Counter</button>
    </div>
  );
};

export default Counter;
profile
코린이

0개의 댓글