解决 React 错误“尝试合并一个对象,却得到 [object Object]”
介绍
在 React 中使用状态变量时,您可能会遇到错误,提示“尝试合并对象,但得到的是 [object Object]”。这通常发生在您直接修改状态并错误地更改其原始结构时。例如,您的状态变量已初始化一个空对象,而您正尝试直接为其分配一个数组。本指南演示了如何正确更改或更新状态而不会遇到任何错误。
在 React 中修改状态
在 React 中,状态被认为是不可变的。这意味着如果你的组件中有这个状态
state={
name: 'Margo'
}
您不能像下面这样直接改变状态。
this.state={
name:'Fuzzy'
}
您必须调用状态上可用的setState()方法来异步更新状态。这种不变性不仅遵循更新状态和重新渲染 DOM 的结构化 React 模式,而且还能防止您编写可能破坏应用程序的不良代码。例如,如果您的状态是一个包含数组的对象,您将调用setState()来更新该数组,从而保持状态的原始结构不变。
React 中的示例
在一个空的 React 项目中,创建一个具有一些预定义状态的简单类组件。
import React, { Component } from 'react'
export default class App extends Component {
state={
todos:[
{id:0,"status": 0, "title": "Wash Dishes"},
{id: 1,"status": 1, "title": "Play Piano"}
]
}
render() {
return (
<div>
</div>
)
}
}
上面的类包含一个简单的状态对象,该对象具有一个名为todos的属性。todos是一个对象数组,其中每个对象代表有关特定待办事项的信息。假设您从服务器获得了新待办事项列表,并且您想将这些待办事项附加到您的状态中,以便将其输出到 DOM 上。
componentDidMount(){
var newTodos = [
{id:2,"status": 0, "tite": "Cook Dinner"},
{id: 3,"status": 0, "title": "Make Bed"}
];
}
newTodos是您想要附加到状态的内容。请考虑新手 React 开发人员在将新对象与状态合并时编写的以下代码。
componentDidMount(){
var newTodos = [
{id:2,"status": 0, "tite": "Cook Dinner"},
{id: 3,"status": 0, "title": "Make Bed"}
];
var newState = {};
newState = newTodos;
console.log(newState);
this.setState(newState);
}
首先创建一个newState变量作为空对象,并将其分配给newTodos。所以现在newState是一个包含来自newTodos的数据的对象数组。然后调用setState()方法并直接将新状态传入其中。你的原始状态是
todos:[
{id:0,"status": 0, "title": "Wash Dishes"},
{id: 1,"status": 1, "title": "Play Piano"}
]
将newTodos合并到你的状态后,你应该期望你的状态变成
todos:[
{id:0,"status": 0, "title": "Wash Dishes"},
{id: 1,"status": 1, "title": "Play Piano"},
{id:2,"status": 0, "tite": "Cook Dinner"},
{id: 3,"status": 0, "title": "Make Bed"}
]
通过在componetDidUpdate()内部将新状态记录到控制台来查看新状态是否确实如上所示
componentDidUpdate(){
console.log(this.state)
}
如果你检查控制台,你会发现你的状态已经偏离了原来的结构,它看起来像这样
{id: 2
这不是您所期望的。新添加的 todos 的每个元素都是状态的直接子属性,而不是todos属性。这不仅会破坏状态结构,还会使您的代码更容易出现错误。此外,在 DOM 上输出所有 todos 也变得困难,因为您必须根据属性的数据结构分别循环遍历它们。在更新状态时,您可能还会遇到错误“尝试合并对象,但得到的却是 [object Object ]”。正确的方法是维护状态的原始结构。
this.setState({...this.state,todos:[...this.state.todos,...newTodos]});
使用扩展运算符,您首先将原始状态复制到新状态,然后将新添加的待办事项附加到状态的todos属性。如果您看到控制台上记录了更新后的状态,则您的状态看起来完全正确,包含一个名为todos的属性,该属性包含所有四个待办事项作为数组的元素。现在,您还可以通过简单地迭代状态的todos属性并输出您希望在 DOM 上呈现的属性,轻松输出所有待办事项。
render() {
return (
<div>
{
this.state.todos.map(todo=><p key={todo.id}>{todo.title}</p>)
}
</div>
)
}
}
看看下面的整个代码。
import React, { Component } from 'react'
export default class App extends Component {
state={
todos:[
{id:0,"status": 0, "title": "Wash Dishes"},
{id: 1,"status": 1, "title": "Play Piano"}
]
}
componentDidMount(){
var newTodos = [
{id:2,"status": 0, "tite": "Cook Dinner"},
{id: 3,"status": 0, "title": "Make Bed"}
];
this.setState({...this.state,todos:[...this.state.todos,...newTodos]});
}
componentDidUpdate(){
console.log(this.state)
}
render() {
return (
<div>
{
this.state.todos.map(todo=><p key={todo.id}>{todo.title}</p>)
}
</div>
)
}
}
结论
修改或更新 React 组件的状态应以正确的方式进行,以避免代码中出现潜在错误。使用 JavaScript 的展开运算符,可以以更简洁、更短的语法修改状态。只需学习较新、更现代的 JavaScript 功能并在代码中使用它们,就可以采用许多良好做法。它们可以帮助您编写简洁、简短、可读且易于维护的代码,并降低出错的可能性。
免责声明:本内容来源于第三方作者授权、网友推荐或互联网整理,旨在为广大用户提供学习与参考之用。所有文本和图片版权归原创网站或作者本人所有,其观点并不代表本站立场。如有任何版权侵犯或转载不当之情况,请与我们取得联系,我们将尽快进行相关处理与修改。感谢您的理解与支持!
请先 登录后发表评论 ~