当前位置: 首页 > 面试题库 >

setState无法正确更新状态

姜嘉荣
2023-03-14
问题内容

抱歉,我真的很想念React中子组件state内部的传递props

我已经实现了一个包含3个组件的待办事项列表。

有一个Form组成部分和一个ListTodo组成部分。状态仅存储App组件中。

import React, {Component} from 'react';
import './App.css';

class App extends Component {

    constructor(props) {
        super(props);
        this.state = {
            tasks: ["un truc", "autre truc"]
        };
        this.addTask = this.addTask.bind(this);
    }

    addTask(task) {
        this.setState({
            tasks: this.state.tasks.push(task)
        })
    }

    render() {
        return (
            <div className="App">
                <Form onTaskAdded={ this.addTask }></Form>
                <ListTodo tasks={ this.state.tasks }></ListTodo>
            </div>
        );
    }
}

class Form extends Component {

    constructor(props) {
        super(props);
        this.state = {
            task: ""
        }

        this.handleChange = this.handleChange.bind(this);
        this.addTask = this.addTask.bind(this);
    }

    handleChange(event) {
        this.setState({
            task: event.target.value
        });
    }

    addTask(event) {
        this.props.onTaskAdded(this.state.task);
        event.preventDefault();
    }

    render() {
        return (
            <form onSubmit={ this.addTask }>
                <input placeholder="À faire" onChange={ this.handleChange }></input>
                <input type="submit"></input>
            </form>
        )
    }
}

class ListTodo extends Component {

    render() {
        const tasks = this.props.tasks.map((t, i) => (
                <li key={i}>{t}</li>
            ))

        return (
            <ul>{tasks}</ul>
        )
    }
}

export default App;

显示器起步不错,因此ListTodo可以看到道具tasks。但是在提交表单后,我收到了以下错误ListTodo.render

TypeError:this.props.tasks.map不是函数

当我console.log时this.props.tasks,我没有得到我的数组,而是数组的长度。

你知道为什么吗?

编辑 :谢谢大家的回答,你是对的。我错过了Array.push的行为。

但是React似乎仍然很奇怪。如果我让错误的代码 this.setState({tasks:this.state.tasks.push(task)})

然后console.log(JSON.stringify(this.state))显示:

{"tasks":["un truc","autre truc","aze"]}

无法令人信任的console.log非常令人不安…


问题答案:

根据MDN DOC:

push()方法将一个或多个元素添加到数组的末尾,并 返回该 数组 的新长度

Array.push从不返回结果数组,它返回数字,因此在添加第一个任务后this.state.tasks成为数字,并且尝试在数字上运行map时会引发错误。

您在这里犯了错误:

addTask(task) {
    this.setState({
        tasks: this.state.tasks.push(task)
    })
}

这样写:

addTask(task) {
    this.setState( prevState => ({
        tasks: [...prevState.tasks, task]
    }))
}

这里的另一项导入是,新状态将取决于先前的状态值,因此this.state,使用updater函数而不是在setState内部使用。

有关编辑部分的说明:

那里发生了两个重要的事情:

1- setState是异步的,因此在setState之后,我们可以期待更新后的状态值。

选中此项以获取有关 setState异步行为的 更多详细信息。

2-
Array.push总是通过将项目推入其中来使原始数组发生变化,因此您可以直接通过改变状态值this.state.tasks.push()

检查 DOC 以获取有关setState的更多详细信息。

检查 MDN文档 中的spread operator (...)

检查以下代码段:

let a = [1,2,3,4];



let b = a.push(5);  //it will be a number



console.log('a = ', a);



console.log('b = ', b);


 类似资料:
  • 我有3个div。当我点击特定的按钮时,每个人都会有类活动。它们的每个div都有一个状态变量,每当它是真的时,我都会向连接到它的div添加class Name='active': 当我点击按钮时,状态改变,但是div没有激活类 当我将函数更改为此时,它会工作: ================================================ =====================

  • 所以我有这个: 只是一个数组的数字例如然而没有给出正确的总数,但?我甚至放了一个超时延迟,看看这是否解决了问题。任何明显的还是我应该发布更多的代码?

  • 问题内容: 所以我有这个: newDealersDeckTotal只是一个数字数组,例如,但是没有给出正确的总数,但是呢?我什至设置了超时延迟,以查看是否可以解决问题。任何明显的还是我应该发布更多代码? 问题答案: 通常是异步的,这意味着在您处于状态时,它尚未更新。尝试将日志放入方法的回调中。状态更改完成后执行:

  • 问题内容: 我觉得我已经在阳光下尝试了所有东西,但是一定缺少一些非常明显的东西。在下面,我试图将一个新项目推入数组并更新状态,但是无论我做什么,状态都不会从初始数组更改。 当我console.log newListItems时,新项目就包括在内,因此到目前为止所有工作都在进行,它是不会更新的实际状态。我想念什么? addItem方法: 我也没有在控制台中收到任何错误消息。 完整代码: 问题答案:

  • 我正在从一个文件导出常量并将其导入另一个文件,如下所示: 常数.js App.js 我希望我的初始状态是在构造函数中设置的,然后在componentWillMount上,我希望使用常量文件中的值设置状态,然后再围绕组件和流添加进一步的逻辑。 但是,我发现,我的状态没有被更新,如果我在调用setState之后记录控制台日志,状态仍然没有定义,如果我引入一个方法,需要state中的值,那么在执行堆栈的

  • 我想问一下,为什么在执行事件时,我的状态没有改变。我已经搜索到需要在构造函数中绑定函数,但是状态仍然没有更新。 下面是我的代码: