React Redux는 앞으로도 Redux Toolkit을 사용하는 것이 좋습니다.

15016 단어 ReactJavaScript
TypeScript로 React를 시작하는 것이 상당히 수월해졌다고 생각합니다.다음 명령을 사용하면 됩니다.
$ npx create-react-app my-app --template typescript
2020년 2월 중순부터 Redux 템플릿을 사용할 수 있으며 다음 명령을 통해 시작할 수 있습니다.
$ npx create-react-app my-app --template redux
# or 
$ npx create-react-app my-app --template redux-typescript
이 Redux 템플릿은 Redux Toolkit을 사용합니다https://redux-toolkit.js.org/
정식으로 사용하는 것은 지금부터다. 하지만 사용하지 않는 상황에 비해 이곳이 편한 곳을 소개한다.

이점


간편한 초기화


다음 middleware가 설정되었습니다.
  • Redux Thunk
  • immutable-state-invariant
  • serializable-state-invariant-middleware
  • Redux Thunk는 비동기 통신에 사용되는 라이브러리이고, 다른 두 개는 개발된middleware로 Redux에서 금지된state 변경을 검사할 수 있습니다.
    또한 Redux Devtools Extension도 활성화됩니다.
    네가 이런 것들을 스스로 응용하고 싶다면 좀 번거로울 것이다.

    createSlice에서 Action 코드가 필요 없습니다.


    이것은 공식 문서에서 발췌한 것이다
    const counterSlice = createSlice({
      name: 'counter',
      initialState: 0,
      reducers: {
        increment: state => state + 1,
        decrement: state => state - 1
      }
    })
    
    const store = configureStore({
      reducer: counterSlice.reducer
    })
    
    const { actions, reducer } = counterSlice
    const { increment, decrement } = actions
    
    
    이렇게 하면 Action, Reducer를 정의할 수 있습니다.나는 이렇게 하면 액션 코드가 거의 없기를 바란다.지금까지는 Component, Action, Reducer에 대해 다소 논리적이지만 Component, Reducer에서는 각자의 책임으로 논리를 설치할 수 있다
    Reducer의 중첩 느낌은 여느 때와 같다.
    const sliceA = createSlice({
      name: "reducerA",
      //...
    })
    const sliceB = createSlice({
      name: "reducerB",
      //...
    })
    
    import { combineReducers } from "@reduxjs/toolkit"
    const mergeReducer = combineReducers({
      reducerA: sliceA.reducer,
      reducerB: sliceB.reducer,
    })
    
    

    비동기식 통신의 이중화

    
    const createUser = createAsyncThunk(
      'users/createUser',
      async () => {
        // API処理
      }
    )
    
    createAsyncThunk는 다음 세 가지 동작을 생성할 수 있습니다.
  • pending
  • fulfilled
  • rejected
  • slice는 extraReducers의builder를 사용하여 추가합니다.이것은createAsyncThunk에서 정의한 Action을 이용하기 위해서입니다.
    reducer.js
    const userSlice = createSlice({
      name: "user",
      initialState: {
        user: null,
      },
      reducers: {},
      extraReducers: builder => {
        builder.addCase(createUser.pending, (state, action) => {})
        builder.addCase(createUser.fulfilled, (state, action) => {})
        builder.addCase(createUser.rejected, (state, action) => {})
      }
    })
    
    
    component.jsx
    import { useDispatch } from "react-redux"
    
    function UserComponent() {
      const dispatch = useDispatch()
    
      const handleSubmit = async () => {
        const resultAction = await dispatch(createUser())
        // createAsyncThunkで生成されるActionと比較して処理を変更できる
        if (createUser.fulfilled.match(resultAction)) {
          // success
        } else {
          // error
        }
      };
      return (
        <div>
          <form></form>
          <button onClick={handleSubmit}>submit</button>
        </div>
      )
    }
    
    

    가장 좋은 일


    RootReducer 유형 정의


    TypeScript로 사용할 때는 준비하는 것이 좋습니다.정의는 다음과 같습니다.
    store.ts
    import { combineReducers, configureStore } from "@reduxjs/toolkit"
    
    export const rootReducer = combineReducers({
      moduleA: moduleAReducer,
    })
    export type RootReducerType = ReturnType<typeof RootReducer>
    
    
    뿌리로서의 리덕터의 유형 정의가 있으면 기분이 편해요.

    디스패치 패키지 사용


    store.ts
    import { configureStore } from "@reduxjs/toolkit"
    const store = configureStore({
      reducer: rootReducer
    })
    export type AppDispatch = typeof store.dispatch
    
    customHooks.ts
    import { useDispatch } from "react-redux"
    function useAppDispatch(): AppDispatch {
      return useDispatch<AppDispatch>()
    }
    
    createAsyncThunk가 형식 정의 오류를 일으키지 않기 때문입니다.

    주의사항


    Immer를 사용하여 Reducer의 Immutable 시작


    아래와 같이state의 코드를 직접 변경하는 것도 문제없습니다.Redux Toolkit은 Immer를 사용하고 실제 state를 변경하는 것이 아닙니다.
    interface CounterState {
      value: number;
    }
    
    const initialState: CounterState = {
      value: 0,
    };
    
    export const slice = createSlice({
      name: 'counter',
      initialState,
      reducers: {
        increment: state => {
          state.value += 1;
        }
      },
    });
    
    

    총결산


    더 이상 번거로운 설정이 없고, Action과 Reducer의 실현도 통일될 수 있다.앞으로 Redux를 시작하는 사람과 그렇지 않은 사람에게도 추천합니다

    참고 자료

  • https://create-react-app.dev/docs/adding-typescript/#installation
  • https://github.com/reduxjs/cra-template-redux
  • https://redux-toolkit.js.org/
  • 좋은 웹페이지 즐겨찾기