TodoList & ReduxToolkit


Redux


TodoListにReduxを適用して作成したい


会社はreduxを使うべきで、しかしredux私は概念さえなくて、だから生存します;redoxを勉強するために、redoxを勉強しなければなりません.まず,TodoListは最低限の機能のみを実現することを決定する.
保留中の事項を追加し、保留中の事項を削除します.

text inputで記事を作成およびコミットするとアイテムが追加され、チェックボックスをクリックするとアイテムが削除されます.まず、国の管理で簡単に実現しました.簡単に成功した.
そしてredixを用いて実装した.大量のシャベルを経て、いったいどうやって作られたのか.

Redux Toolkit + Todo List


まずリデストゥキットの存在を知らなかった...リデスだけを体現している.初めて触れたコンセプトなので難しすぎて、進められない状況で、リデストックであることに気づきました.すぐに乗り換えました.
reduckツールパッケージは、ストレージの構成、createReducer、createAction、createSlice、createSelectorなど、reduceステータス管理を容易に実現します.
まず実装されたコードからコメントを行う.

Redux Toolkit


を選択します。

interface ITodo {
  index: number;
  content: string;
}

interface StoreState {
  todos: ITodo[];
}
storeとtodoで使用するタイプを定義します.ITodo[]のみを使用してstoreのタイプを定義し、store内部にtodo配列がある形で実装します.したがって、selector()を使用してstateをロードすると、todo配列ではなくstateオブジェクトが割り当てられ、配列への直接アクセスが困難になります.
const todos = useSelector((state: ITodo[]) => state);

console.log(todos); // {todos: ITodo[]} <= 요렇게
この場合、stateは配列のみを返し、storeはオブジェクトタイプを返し、reduceが使用するタイプはstoreのpropertyに入ると思います.
const todos = useSelector((state: any) => state);

useEffect(() => {
  console.log(todos.todos); // [todo, todo]
}, [todos]); 
以上のようにtodosをanyタイプに設定し、state内部のtodosを撮影したところ、todos配列出力が正しいことがわかりました.特定のタイプの設定は、createSliceとcombinedReducerでさらに表示されます.

createSlice

export const todoSlice = createSlice({
  name: 'todos',
  initialState: initialState,
  reducers: {
    addTodoList: {
      reducer: (state, { payload }: PayloadAction<{ index: number; content: string }>) => {
        return [...state, { index: payload.index, content: payload.content }];
      },
      prepare: (index: number, content: string) => ({
        payload: {
          index: index + 1,
          content,
        },
      }),
    },
    deleteTodoList: {
      reducer: (state, { payload }: PayloadAction<{ index: number }>) => {
        return [...state.filter((item) => item.index !== payload.index)];
      },
      prepare: (index: number) => ({
        payload: {
          index,
        },
      }),
    },
  },
});

export const { addTodoList, deleteTodoList } = todoSlice.actions;
export const { reducer } = todoSlice;
公式ファイル翻訳のチュートリアルを見て、createActoin、createReducerを直接実現し、それに従って、createSliceだけで簡単に動作とReducerを作ることができ、createSliceでReducerとActionを実現しました.
リズムが上がるにつれて、実施の時は分からなかったが、シュート中にどのように動いているのかを感じた.
name項はstateに含まれるキー値となる.initialstateはtodosのデフォルト値を設定します.Reduserがどんな概念なのか理解しにくい.
これまでReducers内部のaddToDoListとdeleteToDoListはアクションジェネレータであり、prepareはアクション受信したパラメータをペイロードオブジェクトに返すロジックであった.reduceは状態と負荷をパラメータとして受け入れ,状態を更新する方法となる.
下部の{addToDoList,deleteToDoList}と{reduce}はtoDoSliceを動作と再生に分ける.
PayloadAction
シートには負荷戻りタイプを指定できます.Redux toolkitのPayloadActionタイプを使えばいいです.
コメントリンク
prepare
prepareは、負荷に複数のパラメータを追加するために使用されます。
using prepare callbacks to customize action contents

configureStore

const todos = todoSlice.reducer;

const reducers = combineReducers<StoreState>({
  todos,
});

export default function createStore(): Store<StoreState> {
  const store = configureStore({
    reducer: reducers,
  });

  return store;
}
上のコードはstoreを作成するコードです.タイプに挿入するように、reducerをcombinedreducersに統合しないのは、もちろん1つなので、これがSTATEになると思います.コンビネーションReducerは、StoreStateタイプで定義されているReducerをReducerオブジェクト(?)にマージする異なるReducerをマージする方法です.シェイプにマージできます.今は1つしか必要ないので、1つだけ追加しました.これがstatetodosを使用してtodosの配列にアクセスでき、実施部でステータスになります.todosはITodoのレイアウトにアクセスできます.
createStore関数は、StoreStateタイプを表し、StoreStateタイプを返すデータムジェネレータを作成します.
どんな項目でも、推薦者は一人ではありませんが、推薦者が一人しかいない場合、このような組み合わせが良い方法なのか分かりません.

index.tsx

export const store = createStore();

ReactDOM.render(
  <React.StrictMode>
    <Provider store={store}>
      <App />
    </Provider>
  </React.StrictMode>,
  document.getElementById('root'),
);
ここは簡単です.storeオブジェクトを作成し、Providerという高次構成部品のパラメータに入れます.

implement


実施部

function Container() {
  const todos = useSelector((state: StoreState) => state);
  const dispatch = useDispatch();

  function addTodoHandler(event: React.FormEvent<HTMLFormElement>) {
    event.preventDefault();
    const textInput = event.currentTarget.input.name === 'input' && event.currentTarget.input;
    if (textInput.value === '') return;
    const inputText = textInput.value;
    textInput.value = '';
    dispatch(addTodoList(todos.todos.length, inputText));
  }
  
  function deleteTodo(index: number) {
    dispatch(deleteTodoList(index));
  }

  return (
    <StyledContainer>
      <h1>Todo List</h1>
      <FormWrapper onSubmit={(e) => addTodoHandler(e)}>
        <input name="input" type="text" />
        <input type="submit" />
      </FormWrapper>
      <TodoListBox todos={todos.todos} deleteHandler={deleteTodo}></TodoListBox>
    </StyledContainer>
  );
}
todosは,ユーザセレクタによって状態を受信するオブジェクトとなる.dispatchは、アクションジェネレータを使用してステータスを変更する方法になります.
addTodoHandlerはsubmit時のstateです.新しいtodoリストのイベントハンドラをtodoに追加します.text inputからデータを取得し,dispatchとaddToDoListアクションジェネレータを介して新しい保留事項リストを追加するアクティビティを実現した.
deleteTodoは、チェックボックスをクリックしたときにインデックスが付いている保留中のリストを消去します.

render

function TodoListBox(props: TodoListProps) {
  if (props.todos.length === undefined) return <></>;
  const todoLists = props.todos.map((item, index) => {
    return (
      <ListWrapper key={index}>
        <input type="checkbox" onChange={(e) => props.deleteHandler(item.index)} />
        <li>{item.content}</li>
      </ListWrapper>
    );
  });

  return <StyledListBox>{todoLists}</StyledListBox>;
}
これは説明するまでもない

n/a.結論


reduxのstore、action、reduceの概念を理解するのに役立ちます.
しかし,Reduxの具体的な実装方式(一方向データストリーム,サブスクリプション,派遣,コントローラビューなど)はまだ完全に理解されていない.Reduxは今まで見たことのないパターンなので分かりにくいです.これからも勉強しなければなりません.