Next - Redux (toolkit)

Tony·2021년 12월 20일
0

react

목록 보기
44/86

Next에 Redux 세팅

기존 프로젝트 세팅

1. store 세팅

  • reducer
  • enhancer : middleware (+composeWithDevTools)

2. Redux(store)적용 - wrapper (== Provider)

const wrapper = createWrapper<Store>(configureStore, {
  debug: process.env.NODE_ENV === 'development',
});
  • app.tsx에 적용되어 있음
export default wrapper.withRedux(MyApp);

3. reducer

  • state와 action을 param으로 받아서 action에 맞게 state를 변경
import produce from 'immer';

// reducer
const reducer = (state = initialState, action: IAction) => {
  return produce(state, (draft) => {
    switch (action.type) {
      // lecture list initial load
      case LOAD_ALL_LECTURES_REQUEST:
        draft.loadLectureLoading = true;
        break;
    }
  });
};

export default reducer;

4. state 가져오기 - selector

  const { createLectureLoading, createLectureData, createLectureDone } = useSelector(
    (state: RootState) => state.lecture // selector함수를 useSelector 에 전달
  );

5. state 변경(action, dispatch)

const dispatch = useDispatch();

dispatch({
  type: SAVE_COURSE_INFO_REQUEST,
  data,
});

Redux Toolkit

1. store 세팅

const store = configureStore({
  reducer: Reducer<S, A> | ReducersMapObject<S, A>,
  middleware?: ((getDefaultMiddleware: CurriedGetDefaultMiddleware<S>) => M) | M,
  devTools?: boolean | DevToolsOptions, // 안쓰였으나 쓸 것 같음
  preloadedState?: PreloadedState<CombinedState<NoInfer<S>>>, // 안쓰였음
  enhancers?: StoreEnhancer[] | ConfigureEnhancersCallback, // 안쓰였음
})

2. Redux(store)적용

// _app.tsx
import '../styles/globals.css'

import { Provider } from 'react-redux'
import type { AppProps } from 'next/app'

import store from '../app/store'

export default function MyApp({ Component, pageProps }: AppProps) {
  return (
    <Provider store={store}>
      <Component {...pageProps} />
    </Provider>
  )
}

3. reducer

  • store에 있는 state를 변경

4. state 가져오기 - selector

export const selectCount = (state: AppState) => state.counter.value;

const count = useAppSelector(selectCount);
<span>{count}</span>

5. state 변경(action, dispatch)

export const counterSlice = createSlice({
  name: "counter",
  initialState,
  // The `reducers` field lets us define reducers and generate associated actions
  reducers: {
    // 이 안에 있는 함수들이 actionCreator 들이네
    increment: (state) => {
      // Redux Toolkit allows us to write "mutating" logic in reducers. It
      // doesn't actually mutate the state because it uses the Immer library,
      // which detects changes to a "draft state" and produces a brand new
      // immutable state based off those changes
      state.value += 1;
    },
    decrement: (state) => {
      state.value -= 1;
    },
    // Use the PayloadAction type to declare the contents of `action.payload`
    incrementByAmount: (state, action: PayloadAction<number>) => {
      state.value += action.payload;
    },
  },
  // The `extraReducers` field lets the slice handle actions defined elsewhere,
  // including actions generated by createAsyncThunk or in other slices.
  extraReducers: (builder) => {
    builder
      .addCase(incrementAsync.pending, (state) => {
        state.status = "loading";
      })
      .addCase(incrementAsync.fulfilled, (state, action) => {
        state.status = "idle";
        state.value += action.payload;
      });
  },
});
  • slice의 reducers안에 있는 항목들에 대해 자동으로 action creator들이 생성
export const { increment, decrement, incrementByAmount } = counterSlice.actions;
  • 이 action creator를 dispatch에 전달하면 매칭되는 reducer가 실행되고 state값이 변경 됨
console.log("increment() : actionCreator", increment()); // {type: 'counter/increment', payload: undefined}

<button
  className={styles.button}
  aria-label="Increment value"
  onClick={() => dispatch(increment())}
  >

기존 프로젝트 vs Redux Toolkit example

비교without toolkitReudx toolkit
storewrapper(createWrapper)에 store를 전달해서
wrapper로 app을 감싸줌(HOF)
Provider로 감싸는 거랑 똑같음
Provider로 감싸줌(app)
reducerswitch문에서 action(type)을 확인하고 그것에 맞게 state 변경Slice에 reducer들이 포함되어 있고 reducers object에서 key를 골라서 호출하면 reducer에 의해 state가 변경 됨 - 호출방법 : slice.action에 의해 자동으로 매칭되어 생성된 action creator를 dispatch를 통해 호출

참고 문헌

profile
움직이는 만큼 행복해진다

0개의 댓글