减速器中 CRUD 的 "U"(更新)部分出现问题
Issue with the "U" (update) part of CRUD in reducers
我一直在研究无 redux 的 CRUD 项目。结合使用 contextAPI/hooks 创建类别列表。 "CR and D"(创建、读取和删除)部分我已经成功了,但是在 "U"(更新)部分苦苦挣扎,在提交更新更改后我无法让它工作。
从我如何处理减速器组件开始...
reducer.js
import uniqid from 'uniqid';
export const categoryReducer = (state, action) => {
switch (action.type) {
case 'ADD_CATEGORY':
return [
...state,
{
id: uniqid(),
name: action.name,
suffix: action.suffix
}
];
//**MY ISSUES**
case 'UPDATE_CATEGORY':
return (
state.findIndex(item => item.id === action.id),
state.slice(0, action.id, action.name, action.suffix)
);
case 'REMOVE_CATEGORY':
return state.filter(item => item.id !== action.id);
default:
return state;
}
};
'ADD_CATEGORY'
和 'DELETE_CATEGORY'
可以忽略,因为我没有问题。 'UPDATE_CATEGORY'
对我来说有点粗略,我觉得语法不正确。据我了解,为了进行更新更改。需要将所选项目从数组中扫描到匹配的 ID 中。一旦 id 匹配,更改可以在提交后更新。而且我不确定我能否弄清楚如何添加该语法。
现在 handleSubmit
函数中带有调度的编辑表单组件...
EditCategoryForm.js
import React, { useState, useContext, useEffect } from 'react';
//context
import { CategoryContext } from '../contexts/categoryContext';
function EditCategoryForm() {
const { dispatch } = useContext( CategoryContext);
/*Not not get this to work */
const handleSubmit = (e, name, suffix) => {
e.preventDefault();
dispatch({
type: 'EDIT_CATEGORY',
name,
suffix
});
};
const handleChange = e => {
const { name, value } = e.target;
setInputValue(prevState => ({ ...prevState, [name]: value }));
};
return (
<form onSubmit={handleSubmit}>
<h1>Edit</h1>
<input
type="text"
name="name"
value={inputValue.name}
onChange={handleChange}
/>
<input
type="text"
name="suffix"
value={inputValue.suffix}
onChange={handleChange}
/>
<button>Submit Change</button>
<button onClick={() => setEditing(false)}>Cancel</button>
</form>
);
}
export default EditCategoryForm;
同样,我认为语法执行有误。目标是根据输入值分派 name
和 suffix
的单独值。我没有取得任何成功,最近它一直在为我而苦苦挣扎。我该如何解决这个问题?在 reducer 和 dispatcher 中实现 "U" (update) 部分的最佳实践或正确方法是什么?感谢您的帮助,并提前致谢。
在更新案例中,我建议通过您现有的项目进行映射:
- 如果映射的项目与更新的项目具有相同的 id,则替换它
- 否则保留现有项目
代码如下:
case 'UPDATE_CATEGORY':
return state.map(item => {
if (item.id === action.id) {
return {...item, name: action.name, suffix: action.suffix };
}
return item;
});
缺少初始化状态的部分。我假设它是这样的:
const [inputValue, setInputValue] = useState({name: '', suffix: ''})
handleSubmit
函数接收单个参数(事件),您需要使用来自您的状态的值:
// remove the extra parameters
const handleSubmit = (e /*, name, suffix */) => {
e.preventDefault();
dispatch({
type: 'UPDATE_CATEGORY',
id: inputValue.id,
name: inputValue.name,
suffix: inputValue.suffix,
});
};
case 'UPDATE_CATEGORY':
let update_obj = state.find( obj => obj.id === action.id);
update_obj['name'] = action.name;
update_obj['suffix'] = action.suffix;
return [...state, update_obj]
如果我没记错的话,这应该是 return 原始状态,以及更新后的特定元素
或者你可以这样做:
const newArr = state.map( obj => {
if obj.id === action.id{
obj['name'] = action.name;
obj['suffix'] = action.suffix;
}
return obj
});
return newArr;
我一直在研究无 redux 的 CRUD 项目。结合使用 contextAPI/hooks 创建类别列表。 "CR and D"(创建、读取和删除)部分我已经成功了,但是在 "U"(更新)部分苦苦挣扎,在提交更新更改后我无法让它工作。
从我如何处理减速器组件开始...
reducer.js
import uniqid from 'uniqid';
export const categoryReducer = (state, action) => {
switch (action.type) {
case 'ADD_CATEGORY':
return [
...state,
{
id: uniqid(),
name: action.name,
suffix: action.suffix
}
];
//**MY ISSUES**
case 'UPDATE_CATEGORY':
return (
state.findIndex(item => item.id === action.id),
state.slice(0, action.id, action.name, action.suffix)
);
case 'REMOVE_CATEGORY':
return state.filter(item => item.id !== action.id);
default:
return state;
}
};
'ADD_CATEGORY'
和 'DELETE_CATEGORY'
可以忽略,因为我没有问题。 'UPDATE_CATEGORY'
对我来说有点粗略,我觉得语法不正确。据我了解,为了进行更新更改。需要将所选项目从数组中扫描到匹配的 ID 中。一旦 id 匹配,更改可以在提交后更新。而且我不确定我能否弄清楚如何添加该语法。
现在 handleSubmit
函数中带有调度的编辑表单组件...
EditCategoryForm.js
import React, { useState, useContext, useEffect } from 'react';
//context
import { CategoryContext } from '../contexts/categoryContext';
function EditCategoryForm() {
const { dispatch } = useContext( CategoryContext);
/*Not not get this to work */
const handleSubmit = (e, name, suffix) => {
e.preventDefault();
dispatch({
type: 'EDIT_CATEGORY',
name,
suffix
});
};
const handleChange = e => {
const { name, value } = e.target;
setInputValue(prevState => ({ ...prevState, [name]: value }));
};
return (
<form onSubmit={handleSubmit}>
<h1>Edit</h1>
<input
type="text"
name="name"
value={inputValue.name}
onChange={handleChange}
/>
<input
type="text"
name="suffix"
value={inputValue.suffix}
onChange={handleChange}
/>
<button>Submit Change</button>
<button onClick={() => setEditing(false)}>Cancel</button>
</form>
);
}
export default EditCategoryForm;
同样,我认为语法执行有误。目标是根据输入值分派 name
和 suffix
的单独值。我没有取得任何成功,最近它一直在为我而苦苦挣扎。我该如何解决这个问题?在 reducer 和 dispatcher 中实现 "U" (update) 部分的最佳实践或正确方法是什么?感谢您的帮助,并提前致谢。
在更新案例中,我建议通过您现有的项目进行映射:
- 如果映射的项目与更新的项目具有相同的 id,则替换它
- 否则保留现有项目
代码如下:
case 'UPDATE_CATEGORY':
return state.map(item => {
if (item.id === action.id) {
return {...item, name: action.name, suffix: action.suffix };
}
return item;
});
缺少初始化状态的部分。我假设它是这样的:
const [inputValue, setInputValue] = useState({name: '', suffix: ''})
handleSubmit
函数接收单个参数(事件),您需要使用来自您的状态的值:
// remove the extra parameters
const handleSubmit = (e /*, name, suffix */) => {
e.preventDefault();
dispatch({
type: 'UPDATE_CATEGORY',
id: inputValue.id,
name: inputValue.name,
suffix: inputValue.suffix,
});
};
case 'UPDATE_CATEGORY':
let update_obj = state.find( obj => obj.id === action.id);
update_obj['name'] = action.name;
update_obj['suffix'] = action.suffix;
return [...state, update_obj]
如果我没记错的话,这应该是 return 原始状态,以及更新后的特定元素
或者你可以这样做:
const newArr = state.map( obj => {
if obj.id === action.id{
obj['name'] = action.name;
obj['suffix'] = action.suffix;
}
return obj
});
return newArr;