0

私はコーディングにまったく慣れていないので、現在useReducer()React でフックを練習して、単純な todo アプリで状態を管理しています。TOGGLE_TODO アクションを実装しようとすると問題が発生します。配列を使用する前にそれを行ったことがありますが、多くのオブジェクトを操作する可能性が高いため、これを正しくできない理由を理解しようとしています。私は失敗することで学んでいると言えますが、私が学んでいるのは、コンピューターの電源を切って立ち去る方法だけです!

トグルするたびに、spread operator を使用して状態を渡します。すべてのアイテムで試してみました。ログアウトしkeyaction.payload一致していることを確認しました (これは、一致する単純なアラート)。

トグルがまだトグルではないことは承知しています。単純に になろうとしていただけcompleteですtrue

状態を返すために多くのことを試しました。ステートメントの先頭に return を追加しました。途中でいくつかの奇妙なバグに遭遇しました。前述のように、これは今のところ非常に単純な状態ですが、私が取り組んでいる別のプロジェクトではより複雑になるため、useState get は非常に面倒です。

ここで私が間違っていることについての助けをいただければ幸いです。

const initialAppState = {
  isOpen: true,
  todos: {}
};

export const ACTIONS = {
  TOGGLE_MODAL: "toggle-modal",
  ADD_TODO: "add-todo",
  TOGGLE_TODO: "toggle-todo"
};

const reducer = (state, action) => {
  // switch statement for actions
  switch (action.type) {
    case ACTIONS.TOGGLE_MODAL:
      return { ...state, isOpen: !state.isOpen };
    case ACTIONS.ADD_TODO:
      return {
        ...state,
        todos: {
          ...state.todos,
          // Object is created with Unix code as the key
          [Date.now()]: {
            todo: action.payload.todo,
            complete: false
          }
        }
      };
    case ACTIONS.TOGGLE_TODO:
      // Comparing the key and the action payload. If they match, it should set complete to 'true'. This will be updated to a toggle when working. 
      Object.keys(state.todos).map((key) => {
        if (key === action.payload) {
          return {
            ...state,
            todos: { ...state.todos, [key]: { complete: true } }
          };
        }
        return state;
      });
    default:
      throw new Error("Nope. not working");
  }
};

レンダリングでは、 をkeyas として渡しid、ペイロードとともに返されるようにします。これがコンポーネントのdispatch関数です...

const Todo = ({ id, value, dispatch }) => {
  return (
    <div className="todo">
      <h1>{`Todo: ${value.todo}`}</h1>
      <p>Done? {`${value.complete}`}</p>
      <button
        onClick={() =>
          dispatch({
            type: ACTIONS.TOGGLE_TODO,
            payload: id
          })
        }
      >
        Mark as Done
      </button>
    </div>
  );
};

レンダリングはObject.entriesすべて正常に機能するものを使用しています。エラーが出たり、イニシャルtodoが消えたりすることがあったので、状態が正しく更新されていないことはわかっていました。

こちらも CodeSandbox のコードです。動作するようになったらここで更新しますが、ここで数日立ち往生しています。:-(

4

1 に答える 1