gpt4 book ai didi

javascript - 如何在不改变数组的情况下更新此状态?

转载 作者:行者123 更新时间:2023-11-28 11:03:55 26 4
gpt4 key购买 nike

我想知道如何在以下场景中改变状态:

我正在使用 React Hooks。我有一个列出 TodoItemsTodoList。可以单击 TodoItems 来运行名为 toggle 的函数,该函数会切换其 completed 属性。

import React, { useState } from "react";
import TodoItem from "./TodoItem";

export default function TodoList() {
const [todos, setTodos] = useState([
{ text: "Example", completed: false }
]);

const toggle = index => {
const newTodos = [...todos];
newTodos[index].completed = !newTodos[index].completed; // Mutating state?
setTodos(newTodos);
};

return (
<>
{todos.map((item, index) => (
<TodoItem key={index} index={index} todo={item} toggle={toggle} />
))}
</>
);
}

我被告知这是变异状态:

You create a copy of the todos array, but you still mutate an item inside the array:

newTodos[index].completed = !newTodos[index].completed;

Spreading the array only creates a shallow copy of the array, but the original todo object is not copied and thus mutated.

那么,在不改变状态的情况下处理这个问题的正确方法是什么?我尝试传递 prevTodos 参数,但状态没有更新:

const toggle = index => {
setTodos(prevTodos => {
prevTodos[index].completed = !prevTodos[index].completed;
return prevTodos;
});
};

更新:我已经查看了你们推荐的帖子。这是一个解决方案,尽管我想知道是否有更清晰的方式来表达它:

const toggle = index => {
setTodos(
todos.map((todo, i) =>
i === index ? { ...todo, completed: !todo.completed } : todo
)
);
};

更新2:谢谢大家。我在下面发布了解决方案。 StackOverflow 两天内不会让我接受它,但我会接受。建议帖子中接受的答案建议使用第三方库,并且它不使用 React Hooks,所以我不认为这个问题是重复的。

最佳答案

没错,避免这个问题最简单的方法就是avoid mutating data

实现此目的的一种方法是使用函数方法,特别是使用非变异数组方法,例如 .map :

function TodoList() {
const [todos, setTodos] = React.useState([{
text: "Example",
completed: true
}]);

const toggle = index => {
const updatedTodos = todos.map((todo, i) => {
if (i === index) {
todo.completed = !todo.completed;
}
return todo;
});
setTodos(updatedTodos);
};

return (
<React.Fragment >
{todos.map((item, index) => (
<p
key={item.text}
onClick={() => toggle(index)}
className={item.completed ? "completed" : ""}
>
{item.text}
</p>
))}
</React.Fragment>
);
}

ReactDOM.render( < TodoList / > , document.getElementById('root'))
.completed {
text-decoration: line-through;
}
<script src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>
<div id="root"></div>

关于javascript - 如何在不改变数组的情况下更新此状态?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60230221/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com