Redux分派不会使用新的负载对象更新状态数组

yfwxisqw  于 2022-11-12  发布在  其他
关注(0)|答案(1)|浏览(178)

我决定把Redux添加到我的宠物项目中(惊喜,todolist)。
下面是添加条目函数:

const [todoEntry, setTodoEntry] = useState('');

  const addNewEntry = (e) => {

    e.preventDefault();

    // console.log(todoEntry);

    dispatch({

      type: ADD_TODO,

      payload: {

        prodName: todoEntry,
        done: false,
        favorite: false,
        edit: false,
        id: uuid()
      }
    })

    setTodoEntry('');

todoEntry来自另一个组件,如下所示:

<input

 id='standartInput'
 style={{minWidth: '250px'}}
 value={todoEntry}
 onChange={e => setTodoEntry(e.target.value)}
 type='text'
 placeholder='Add new entry (max 55 symbols)' />

此外,我还使用一些钩子来管理我的状态:

const myTodoItems = useSelector((state) => state.todos[0])

  const dispatch = useDispatch()

  const [data, setData] = useState(myTodoItems);

最后,减速器:

import { todolist } from "./todolist"
import { ADD_TODO } from '../Store/todoactions'

export const todoReducer = (state = [todolist], action) => {

    switch (action.type) {

        case ADD_TODO: {

            const newItem = action.payload

            console.log(newItem)
            console.log(todolist)

            return ([...todolist, newItem])

        }

        default:
            { return state }
    }
}

问题在于:

  • todolist存在,我可以在浏览器控制台上看到
  • newItem也存在,我也可以在浏览器控制台看到

但是!点击“添加”按钮时,状态未更新。
我做错了什么?

  • 谢谢-谢谢
z4bn682m

z4bn682m1#

const myTodoItems = useSelector((state) => state.todos[0])

您似乎只选择了第一个项目,因此看不到其余项目也就不足为奇了。

const [data, setData] = useState(myTodoItems);

这看起来像一个反模式,为什么需要一个状态变量来表示Redux已经跟踪的东西呢?
您还应该使用Redux Toolkit,不建议直接使用Redux。

编辑:

谢谢你的codesandbox,现在问题很清楚了。
您使用Redux和React状态来处理相同的数据,例如,您通过Redux添加待办事项,但使用React状态来完成它们。React/Redux中一个非常重要的原则是拥有单一的事实来源,但在您的情况下,您有两个用于待办事项的事实来源:Redux存储和useState挂钩。您使用React状态进行呈现,并使用Redux状态对其进行初始化,但在添加待办事项时不更新它,因此UI显示过时的信息。
有时候使用Redux,有时候使用useState,只要是针对独立的数据段就可以了,但是对于相同的数据,您需要进行选择。
请记住,每次使用useState(initialState)时,您都创建了一个新的状态变量/真理源,它将变得与初始状态不同。有时这正是您想要的,但在这里不是。
因此,我建议删除useState,并通过Redux对待办事项进行修改(编辑、完成等)。
您可以将一些内容作为React状态(例如布尔值“我们当前是否正在编辑此特定的todo项”),但直接在TodoItem组件中使用简单的useState(false)会容易得多。

相关问题