使用React中的分派用新值替换数组中的项目

问题描述 投票:1回答:1

我有一个初始数组,可以将其添加和删除,在那里没有问题。

const initialItems = [
    {
        id: Date.now(),
        text: 'Get milk',
    },
    {
        id: Date.now(),
        text: 'Get eggs',
    },
]

..但是我试图找出如何使用分派功能有效地编辑其中一项的文本。

我的调度看起来像这样:

const editItemHandler = () => {
    dispatch({
        type: 'EDIT_ITEM',
        id: Date.now(),
        text: itemInputRef.current.value,
        index,
    })
}

仅传递输入的值

<input
    autoFocus
    type='text'
    ref={itemInputRef}
    onKeyDown={(e) => {
        if (e.key === 'Escape') {
            setToggle(!toggle)
        }
        if (e.key === 'Enter') {
            // Dispatch
            editItemHandler()
            setToggle(!toggle)
        }
    }}
/>

我的reduce文件看起来像这样:

const itemReducer = (state, action) => {
    switch (action.type) {
        case 'ADD_ITEM': {
            return [
                ...state,
                {
                    id: action.id,
                    text: action.text,
                },
            ]
        }
        case 'EDIT_ITEM': {
            // Attempt 1
            return [...state.splice((item, index) => index, 1, action.text)]
            // Attempt 2
            return [
                ...state.filter((item, index) => index !== action.index),
                {
                    id: action.id,
                    text: action.text,
                },
           ]
        }
        case 'DELETE_ITEM': {
            return [...state.filter((item, index) => index !== action.index)]
        }
        default: {
            return state
        }
    }
}

export default itemReducer

我已经用'EDIT_ITEM'类型尝试过的2种方法发表评论。

方法1只是删除了该项目,并在数组的底部添加了一个新值,尽管这不是我想要的,所以我不得不在此之后尝试重新排序。

方法2正在使用拼接,我认为这是用指定值替换项目的方法。但是,它返回的只是带有原始文本的“已编辑”(因此甚至不会被编辑),并删除其他所有内容。

[有人可以帮助我了解我如何错误地使用此功能,或者是否有更好的方法来编辑项目。我显然做错了,但不知道是什么。我已经搜索并尝试了各种方法都无济于事,因此将不胜感激。

理想情况下,我希望该项目也保持与以前相同的ID,因此,在这一点上如何保留该ID是一个加号,但并不紧急。

reactjs react-hooks dispatch use-reducer
1个回答
0
投票

要更新数组中的项目,您有多种选择:

case 'EDIT_ITEM': {
    // using map
    return state.map((item, i) => 
                    i === action.index ? { id: action.id, text: action.text } : item
    // using slice
    return [
      ...state.slice(0, action.index),
      { id: action.id, text: action.text },
      ...state.slice(action.index+1)
    ]

这是splice的不正确使用

return [...state.splice((item, index) => index, 1, action.text)]

因为splice返回包含已删除元素的数组,并且它不接受函数作为第一个参数,而是将要开始更改数组的索引。

正确的拼接方式:

case 'EDIT_ITEM': {
    // using splice
    let newState = [ ...state ]
    newState.splice(action.index, 1, { id: action.id, text: action.text })
    // or you can directly do
    newState[action.index] = { id: action.id, text: action.text }
    // and return the new state
    return newState;
© www.soinside.com 2019 - 2024. All rights reserved.