我不确定使用Date.now

问题描述

我对编码还很陌生,我目前正在React中练习useReducer()钩子,以在一个简单的todo应用程序中管理某些状态。 尝试实施TOGGLE_Todo操作时遇到麻烦。我在使用数组之前就已经做到了,但是由于我可能要处理很多对象,因此我试图弄清楚为什么我做不到这一点。我会说我通过失败来学习,但是我所学习的只是如何关闭计算机并走开!

每次切换时,我都使用传播操作符传递状态,在所有项目中都尝试了此操作,并注销了keyaction.payload以确保我正在找到一个匹配项(当我对匹配项进行简单提醒时,它会起作用。)

我知道该切换还不是切换,我只是想简单地将complete设为true

我已经尝试了多种方法来返回状态,已经在语句的开头添加了return,并且在此过程中遇到了一些奇怪的错误。如前所述,目前这是非常简单的状态,但是在我正在处理的另一个项目中它将变得更加复杂,因此useState变得非常混乱。

对于我在这里做错的任何帮助,将不胜感激。

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");
  }
};

在渲染中,我将key作为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会消失,所以我知道状态没有正确更新。

这里是code on CodeSandbox too。如果可以运行,我会在这里更新,但是我被困在这里几天了。 :-(

解决方法

您快到了,用Date.now()为项目建立索引的好主意!
在TOGGLE_TODO案例中只有几个问题:

  • 您的reducer应该总是返回一个状态,您的return语句应该在这种情况的结尾,但是您将其与地图的函数放在一起了
  • 您的化简应该计算一个新状态,而不是改变当前状态。因此,您必须使用complete属性创建一个新的todo对象。

这是怎么回事:

    case ACTIONS.TOGGLE_TODO:
      const newTodos = Object.keys(state.todos).map((key) => {
        if (key === action.payload) {
          return { ...state.todos[key],complete: true } // create a new todo item
        }
        else {
          return state.todos[key]; // keep the existing item
        }
      });
      return {...state,todos: newTodos};