React|ステータス管理:Redux


Reduxの核心原則

  • Single source:storeは1つしかなく、すべてのアプリケーションのステータスがここに保存されています.
  • 不変性:ステータスは読取り専用であり、変更するには「すべてのステータス」を変更する必要があります.再生時には、新しいオブジェクトまたは新しいアレイを作成する必要があります.
  • Pure関数:ステータスの変更はサイドエフェクトを作成しないでください.
  • 👉 Reducerでは、ステータスを変更することはできません.「新しいステータス」に戻る必要があります.
    👉 変更を作成するにはdispatchを使用する必要があります.

    1. Action

  • 状態変更の概念
  • jsオブジェクト
  • の任意の形式で、主にタイプと負荷を含む
    const action1 = {
      type: "namespace/getMyData",
      payload : {
      	id: 123
      }
    };
    
    👉 分割は小さな状態の変更を表し,複数のactionを結合して複合形状を表すのに非常に有用である.

    2. Action Creator

  • の動作を生成する関数
  • .
  • アクションを直接生成するよりもaction creatorを使用すると再利用性が高く、レイヤを追加できます.
    👉 idを取得してaction objectを作成する
    👉 別の形式のlayer(id:String(id))です.slice(1)部分
    👉 addObject(id)を超えるとアクション
  • が作成されます.
    const addObj = (id) => {
      type: 'namespace/getMyData',
      payload: {
        id: String(id).slice(1)
      }
    }

    3. Store

  • アプリケーション全体の状態を保存する
  • 操作に従って、減速機に新しい状態を作成し、storeに状態を格納します.
  • の状態は変化せず、動作が発生するたびに新しいオブジェクト
  • が作成される.
    const store = createStore(reducer, initialState);

    4. Reducer

  • の行動を受け入れ、新しい国を創造します.
    👉 console.log, axios.get()ランプは入るべきではありません.
  • const Reducer = (state, action) => {
      switch (action.type) {
        case "namespcae/getMyData":
          const obj = {id: action.payload.id}
          return {
            ...state, obj
          };
        default:
          return state;
      }
    };

    5. Dispatch

  • actionをreducxに送信する関数
  • dispatchの後、actionはミドルウェアを介してreduceに到達する.
    👉 dispatch(action object) -> middleware -> reducer
  • dispatch()内でactionオブジェクトを生成し、それを渡す必要があります.
  • function MyApp() {
      const dispatch = useDispatch()
      
      return (
        <button onClick={
          () => dispatch(addObj(1234))
        }>Submit</button>
      )
    }

    6. Selector


    storeから特定のステータスセグメントを取得する関数
  • storeのstateは、元のデータを格納し、計算された値をセレクタとしてインポートすることができる.
  • function MyApp() {
      const dispatch = useDispatch()
      const obj = useSelector(state => state.obj)
      
      return (
        <button onClick={
          () => dispatch(addObj(1234))
        }>Submit</button>
      )
    }
    ⚡ flux : action -> dispatch -> reducer -> store -> selector
    👉 Actionが入るとdispatchはreduceで渡され、reduceはactionタイプに応じて新しいstateを返します.これはstoreに保存され、セレクタを使用して保存されたステータスが使用されます.

    Reduxの構造

  • Middleware:action objectが減速機に入る前に動作します.
  • 強化:Reduxを状態の周りに拡張します.
    👉 例はMiddlewareです.
    👉 Middlewareは、actionオブジェクトがpromiseを返すかどうかを確認します.
  • Redux-toolkitの利用

  • redux公式推奨アシスタントライブラリ.
    👉 あらかじめredux-devtools、immerjs、redux-thunk、reselectなどのライブラリが含まれています.
  • 1. configureStore


    パッケージ
  • ReduxのcreateStore関数.
    👉 createStoreを使用する場合よりも簡単に作成できます.
  • const store = configureStore({
    	reducer : {
        	posts: postsReducer,
            users: usersReducer
        }
    })

    2. createAction

  • Actioncreatorを作成する関数
  • で作成したaction creatorにデータを渡すと、ペイロードフィールドに入ります.
  • const addPost = createAction('post/addPost')
    
    addPost({title: 'post 1'})

    3. createReducer

  • 減速機を製造する
  • builderのaddCaseメソッドを使用して、各アクションのステータス変更を定義します.
  • 内部では
  • immerjsを使用するため、変更したコードを可変コードで簡単に記述できます.
  • const postsReducer = createReducer(initState,
        builder => {
          builder.addCase(addPost, (state, action) => {
            state.posts.push(action.payload)
          })
        }
      )

    4. createSlice

  • Sliceは、action creator、reduceなど、個別に作成する必要がある複数のreduceインプリメンテーションボディのセットを1つのオブジェクトにします.
  • const postsSlice = createSlice({
      name:'posts',
      initialState,
      reducers: {
        addPost(state, action) {
          state.postsSlice.push(action.payload)
        }
      }
    })
    
    // 사용
    const { addPost } = postsSlice.actions
    const reducer = postsSlice.reducer

    5. createSelector

  • stateを使用して特定のデータを返します.
  • 冗長ではキャッシュ管理が提供され、パフォーマンスの向上に役立ちます.
  • const postsSelector = state => state.posts
    const userSelector = state => state.user
    
    const postsByUserIdSelector = createSelector(
      postsSelector,
      userSelector,
      (posts, user) => {
        posts.filter(post => post.username == user.username)
      }
    )

    ReduxをReactに接続する


    1. Provider

  • Redux StoreとReactを接続するには、プロバイダを使用して構成部品をラップする必要があります.
  • providerでレンダリングされた構成部品はstateにアクセスできません.
  • function App() {
      return (
        <Provider store={store}>
           <div>소개글입니다.</div>
        </Provider>
      );
    }

    2. useDispatch


    API
  • reducxをインポートするためのdispatch
    ステータス変更のためにactionオブジェクトを
  • dispatch関数に渡します.
  •  const dispatch = useDispatch();
     
     <Button onClick={() =>
        dispatch(changeTheme(theme === "light" ? "dark" : "light"))
     }>

    3. useSelector


    API
  • Redux Storeデータ取得用
  • セレクタ機能をパラメータに変換します.
  • function Header() {
      const dispatch = useDispatch();
      const theme = useSelector((state) => state.theme);
      <Button onClick={() =>
        dispatch(changeTheme(theme === "light" ? "dark" : "light"))
     }>

    Reduxによる非同期処理

  • の非同期にミドルウェアを追加する必要があります.
  • redux-thunkは、Promiseを使用して非同期操作を簡単に処理できるミドルウェアです.
    👉 このほか、redux-saga、redux-observableなどがあります.
  • 1. createAsyncThunk

  • redux-toolkitは、デバッガとしてthunkミドルウェアを追加しました.
  • redux-toolkitはcreateAsyncThunk APIを提供する.
  • 使用方法

  • は、2つのパラメータ「action type」、「async callback(ペイロード作成者)」を受信する.
  • createeasyncThunkによって作成されたaction creatorは4つの関数で構成されています.
    👉 addPost:async関数の割り当て関数
    👉 addPost.pending:承諾の作成時に発生するアクション
    👉 addPost.完了:完了時に発生するアクション
    👉 addPost.拒否:拒否されたときに発生する動作
  • const addPost = createAsyncThunk('posts/addPost',
      async (title) => {
        const result = await PostAPI.addPost({ title })
        return result.data
      }
    )
    
    useEffect(() => {
      dispatch(addPost("post 1"))
    }, [])
  • createSliceのextrareducers関数を使用してbuilderにさまざまな状況のreduserを追加できます.
    👉 すなわちpending,defected,reduserにそれぞれのケースのreduserを追加することができる.
  • 2.連続非同期処理

  • thunk関数を発行するとpromiseが返されます.その後、()メソッドを使用して連続的な非同期処理を継続することができる.