在 React 中使用分派将数组中的项目替换为新值
Replace item in array with new value using dispatch in React
我有一个初始数组,可以添加和删除,没有问题..
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)
}
}}
/>
我的减速器文件如下所示:
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 使用拼接,我认为这是用指定值替换项目的方法。然而,所有 returns 只是 'edited' 的原始文本(因此甚至没有编辑),并删除所有其他内容。
我怎么会错误地使用此功能,或者是否有更好的方法来就地编辑项目?我显然做错了什么,但无法弄清楚是什么。我搜索并尝试了各种方法都无济于事。
理想情况下,我希望该项目也保持与以前相同的 ID,所以如何保持它会是一个加号。
要更新数组中的项目,您有多种选择:
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 return 一个包含 已删除元素的数组 ,并且它不接受函数作为第一个参数,而是接受索引开始更改数组。
拼接的正确方法:
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;
我有一个初始数组,可以添加和删除,没有问题..
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)
}
}}
/>
我的减速器文件如下所示:
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 使用拼接,我认为这是用指定值替换项目的方法。然而,所有 returns 只是 'edited' 的原始文本(因此甚至没有编辑),并删除所有其他内容。
我怎么会错误地使用此功能,或者是否有更好的方法来就地编辑项目?我显然做错了什么,但无法弄清楚是什么。我搜索并尝试了各种方法都无济于事。
理想情况下,我希望该项目也保持与以前相同的 ID,所以如何保持它会是一个加号。
要更新数组中的项目,您有多种选择:
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 return 一个包含 已删除元素的数组 ,并且它不接受函数作为第一个参数,而是接受索引开始更改数组。
拼接的正确方法:
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;