我有一个名单的名字要呈现。列表由搜索输入筛选,但也由gender_id过滤。
问题是,当我更新数组中对象的saved_id时,视图不会改变。我的子组件有一个按钮,如果saved_id是1,输出'Save‘,如果saved_id是2,输出'Remove’。在更新状态后,我可以同时输出‘name’和‘searchFilteredNames’数组,并且都可以得到更新。但是,我使用.map()来呈现列表的const‘性别筛选名称’由于某种原因没有捕捉到更改。知道为什么会这样吗?
父组件(带有名称的表):
export default function Names(props) {
/* Raw list */
const [names, setNames] = useState([]);
/* Search filtered list */
const [searchFilteredNames, setSearchFilteredNames] = useState([...names]);
/* Gender filter */
const [genderFilter, setGenderFilter] = useState(1);
/* Show only names where gender_id is equal to gender filter AND status === 1 */
const genderFilteredNames = searchFilteredNames.filter((name) => {
return name.status_id === 1 && name.gender_id === genderFilter;
});
/* Get names from Database on render */
useEffect(() => {
getNames();
}, []);
/* Update search-filtered array on root array update */
useEffect(() => {
setSearchFilteredNames(names);
}, [names]);
/* Get names */
function getNames() {
axios.get("http://localhost:3001/select").then((response) => {
setNames(response.data);
});
}
/* Update object in array */
function updateSave(id, savedId) {
// Make copy of original array
let newNames = [...names];
// Get index of object to update
for (var index = 0; index < names.length; index++) if (names[index].id === id) break;
// Update object value
newNames[index].saved_id = savedId;
// Set the state to new copy
setNames(newNames)
}
/* Render names */
function renderNames() {
return genderFilteredNames.map((name) => (
<Name
key={name.id}
id={name.id}
name={name.name}
saved={name.saved_id}
gender_id={name.gender_id}
use={() => handleUse(name.id)}
save={() => handleSave(name.id)}
/>
));
}
...
子组件(单行):
export default function Name(props) {
const [name, setName] = useState(props.name);
const [saved, setSaved] = useState(props.saved);
const useFn = props.use;
const saveFn = props.save;
function savedStatus() {
return saved === 1 ? <>Save</> : <>Remove</>;
}
return (
<>
<tr>
<td>{name}</td>
<td className="actions-2">
<button className="btn btn-tan" onClick={useFn}>
<FaRegEdit />
Use
</button>
<button className="btn btn-tan" onClick={saveFn}>
<GiSaveArrow />
{savedStatus()}
</button>
</td>
</tr>
</>
);
}
发布于 2021-04-05 20:18:00
我意识到它为什么不起作用..。我在子组件中使用useState作为saved_status,而不是用setState更新它.
这里:
export default function Name(props) {
const [name, setName] = useState(props.name);
const [saved, setSaved] = useState(props.saved);***** HERE ******
改为:
export default function Name(props) {
const name = props.name;
const saved = props.saved;
发布于 2021-04-05 14:19:42
问题是,您正在直接改变一个状态对象,而不能使用React状态。这里是:
function updateSave(id, savedId) {
// Make copy of original array
let newNames = [...names];
// Get index of object to update
for (var index = 0; index < names.length; index++) if (names[index].id === id) break;
// Update object value
newNames[index].saved_id = savedId; // <========================== *** here
// Set the state to new copy
setNames(newNames)
}
相反,您必须在所创建的新数组的元素中设置一个新对象:
function updateSave(id, savedId) {
// Make copy of original array
let newNames = [...names];
// Get index of object to update
for (var index = 0; index < names.length; index++) if (names[index].id === id) break;
// Update object value
newNames[index].saved_id = {...newNames[index], saved_id = savedId}; // *** here
// Set the state to new copy
setNames(newNames)
}
现在,React将看到对象与前一个对象不一样,并重新呈现它。
不管值多少钱,我可能会用不同的方式来写这个函数:
function updateSave(id, savedId) {
const newNames = names.map(name => {
if (name.id === id) {
// This is the one we're updating, update it
return {...name, saved_id = saveId};
}
return name; // No change
})
setNames(newNames);
}
或者,如果你追求的是超简洁(我真的不喜欢;我更喜欢调试的方便性,而把小型化留给小型化,尽管这个特定的成语在React或其他不变的代码中相当常见),那么:
function updateSave(id, savedId) {
setNames(names.map(name =>
name.id === id ? {...name, saved_id: saveId} : name
));
}
https://stackoverflow.com/questions/66954422
复制相似问题