我刚刚开始拿起react.js所以我通过了很多教程,我偶然发现了这一点,基本上是指从状态中删除一个项目。
这就是那个家伙向我介绍删除功能的方式
delTodo = id => {
this.setState({
todos: [...this.state.todos.filter(todo => todo.id !== id)]
});
};
由于我对javascript不太熟悉,我很难弄清楚< code >是什么...操作员正在做什么,以及他在给定场景中使用它的确切原因。因此,为了更好地理解它是如何工作的,我在控制台上玩了一会儿,我意识到< code>array = [...数组]。但这是真的吗?这个钻头和上面那个做的是一样的吗?
delTodo = id => {
this.setState({
todos: this.state.todos.filter(todo => todo.id !== id)
});
};
有没有更有经验的人能向我解释一下,为什么他选择使用那种方法,而不是我提出的方法?
由于. filter
为您提供了一个新数组(而不是改变源数组),它是可以接受的并导致相同的行为,因此在这里进行扩展是多余的。
不可接受的是:
const delIndex = this.state.todos.findIndex(todo => todo.id !== id);
this.state.todos.splice(delIndex, 1); // state mutation
this.setState({
todos: this.state.todos
});
< code>slice也可以:
const delIndex = this.state.todos.findIndex(todo => todo.id !== id);
this.setState({
todos: [
...this.state.todos.slice(0, delIndex),
...this.state.todos.slice(delIndex + 1)
]
});
如果你改变了状态(保持引用不变), React可能无法确定你的状态的哪一部分实际上改变了,并可能在下一次渲染时构造一个与预期不同的树。
为什么要使用spread运算符呢?
扩展运算符…
通常用于创建数组或对象的浅层副本。当你试图避免改变值时,这是特别有用的,因为不同的原因,这是值得鼓励的。太长,读不下去了具有不可变值的代码更容易推理。这里的答案很长。
为什么传播运算符在反应中使用如此普遍?
在反应中,强烈建议避免 this.state
的突变,而是调用 this.setState(newState)。
直接改变状态不会触发重新渲染,并且可能导致糟糕的用户体验、意外行为甚至错误。这是因为它可能会导致内部状态与正在呈现的状态不同。
为了避免操纵值,使用扩展运算符创建对象(或数组)的派生,而不改变原始值已成为常见做法:
// current state
let initialState = {
user: "Bastian",
activeTodo: "do nothing",
todos: ["do nothing"]
}
function addNewTodo(newTodo) {
// - first spread state, to copy over the current state and avoid mutation
// - then set the fields you wish to modify
this.setState({
...this.state,
activeTodo: newTodo,
todos: [...this.state.todos, newTodo]
})
}
// updating state like this...
addNewTodo("go for a run")
// results in the initial state to be replaced by this:
let updatedState = {
user: "Bastian",
activeTodo: "go for a run",
todos: ["do nothing", "go for a run"]
}
为什么在示例中使用spread运算符?
可能是为了避免意外的状态突变。虽然< code>Array.filter()不会改变原始数组,并且在react状态下使用是安全的,但有几个其他方法会改变原始数组,因此不应在状态下使用。例如:<代码>。push(),< code >。pop(),< code >。splice()。通过在对数组调用操作之前展开数组,可以确保不会改变状态。也就是说,我认为作者打错了,而是这样写的:
delTodo = id => {
this.setState({
todos: [...this.state.todos].filter(todo => todo.id !== id)
});
};
如果您需要使用其中一个变异函数,您可以选择以下列方式将它们与spread一起使用,以避免变异状态和潜在的应用程序错误:
// here we mutate the copied array, before we set it as the new state
// note that we spread BEFORE using an array method
this.setState({
todos: [...this.state.todos].push("new todo")
});
// in this case, you can also avoid mutation alltogether:
this.setState({
todos: [...this.state.todos, "new todo"]
});
根据文档:
永远不要变异<code>这个。直接声明,因为之后调用setState()
可能会替换您所做的突变。处理<code>这个。状态,就好像它是不可变的。
因此,在您提到的教程中的示例中,您不需要创建阵列的副本来更新状态。
// GOOD
delTodo = id => {
this.setState({
todos: this.state.todos.filter(...)
})
}
<code>数组。filter方法创建一个新数组,并且不会改变原始数组,因此不会直接改变您的状态。这同样适用于<code>Array等方法。map或Array.concat
。
如果你的状态是一个数组,并且你正在应用可变的方法,你应该复制你的数组。
查看更多内容,了解哪些< code>Array方法是可变的:
但是,如果您要做如下事情:
// BAD
delTodo = id => {
const todos = this.state.todos
todos.splice(id, 1)
this.setState({ todos: todos })
}
然后您将直接改变状态,因为<code>Array。splice更改现有数组的内容,而不是在删除特定项后返回新数组。因此,您应该使用排列运算符复制阵列。
// GOOD
delTodo = id => {
const todos = [...this.state.todos]
todos.splice(id, 1)
this.setState({ todos: todos })
}
与对象
类似,应应用相同的技术。
// BAD
updateFoo = () => {
const foo = this.state.foo // `foo` is an object {}
foo.bar = "HelloWorld"
this.setState({ foo: foo })
}
上面的内容直接改变了你的状态,所以你应该复制一份,然后更新你的状态。
// GOOD
updateFoo = () => {
const foo = {...this.state.foo} // `foo` is an object {}
foo.bar = "HelloWorld"
this.setState({ foo: foo })
}
希望这有帮助。
当react组件状态发生更改时,将调用render方法。因此,对于任何状态更改,都可以在呈现方法体中执行操作。那么setState回调是否有特定的用例?
React引入了新的静态方法,它在每个呈现方法之前都会被调用,但为什么呢?在prop change之后调用它对我来说是有意义的,但是在之后调用它就没有意义了,也许我错过了什么。 我根据公司的要求创建了一个组件,在组件中日期是从道具控制的。我在组件中有以下状态。 是的,我在中创建了一个额外的变量来跟踪是否由于而被调用,但我认为这不是正确的方法。 或者是我做错了什么或者遗漏了什么,或者不应该在之后调用
问题内容: 我在ReactJS项目中一直在使用babel的async await。我发现可以方便地与React setState一起使用,我想更好地理解它。考虑以下代码: 我的意图是让异步验证代码在组件更新后运行。而且有效!生成的控制台日志显示: 验证代码仅在handleChange更新状态并呈现新状态后运行。 通常要在状态更新后运行代码,您必须在this.setState之后使用回调。这意味着,
问题内容: 我试图了解某些“魔术”行为的根本原因,但我无法完全解释,而从阅读ReactJS源代码中看不出来。 当响应输入中的事件而同步调用该方法时,所有操作均按预期进行。输入的“新”值已经存在,因此DOM实际上并未更新。这是非常理想的,因为这意味着光标不会跳到输入框的末尾。 但是,当运行具有完全相同结构但 异步 调用的组件时,输入的“新”值似乎不存在,从而导致ReactJS实际触摸DOM,这将导致
本文向大家介绍react多个setState调用的原理是什么?相关面试题,主要包含被问及react多个setState调用的原理是什么?时的应答技巧和注意事项,需要的朋友参考一下 当遇到多个setState调用时,它会提取单次传递给setState的对象,把它们合并在一起形成一个新的单一的对象,并用这个单一的对象去做setState的事情
问题内容: 我已经安装了模块。 模式集为。要使用它,我必须运行以下选择: 我正在尝试使用运算符运行一条语句,并收到以下消息。 运行或操作员需要什么? 问题答案: 这很可能是的问题。run: 是否包含安装pg_trgm的架构?如果没有,请包括在内。 另外,您可以使用结构对函数进行模式限定-甚至运算符: 使它独立于。