当给组件状态赋值时,为什么console.log 会打印之前的状态?

IT技术 javascript reactjs
2021-02-07 11:25:51

我正在将数字值从 Numbers 组件发送到 Main 组件。一切正常,直到我在我的 Main 组件中将该值设置为该组件的状态。

var Numbers = React.createClass({
    handleClick: function(number){
        this.props.num(number)
    },
    render: function(){
        return (
            <div>
                <button onClick={this.handleClick.bind(null, 1)}>1</button>
                <button onClick={this.handleClick.bind(null, 2)}>2</button>
                <button onClick={this.handleClick.bind(null, 3)}>3</button>
            </div>
        )
    }
})

var Main = React.createClass({
    getInitialState: function(){
        return {
            number: 0
        }
    },
    handleCallback: function(num){
        console.log("number is right here: " + num);
        this.setState({
            number: num
        })
        console.log("but wrong here (previous number): " + this.state.number)
    },
    render: function() {
        return (
            <Numbers num={this.handleCallback} />
            //<SomeComponent number={this.state.number} />
        )
    }
});

React.render(<Main />, document.getElementById('container'));

为什么会这样?其次console.loghandleCallback功能打印之前的数量,而不是它的数量num参数。我需要正确的数字才能处于我的状态,因为我将立即将其作为SomeComponent组件中的props发送

https://jsfiddle.net/69z2wepo/13000/

5个回答

文档

setState() 不会立即改变 this.state 而是创建一个挂起的状态转换。调用此方法后访问 this.state 可能会返回现有值。无法保证对 setState 调用的同步操作,并且可能会批量调用以提高性能。

如果要在调用 后打印更改setState,请使用可选的回调参数:

this.setState({
    number: num
}, function () {
    console.log(this.state.number);
});
你会如何解决这个问题SomeComponent我现在知道为什么它不起作用,但我不知道如何仅在 this.state 已更新时才能将状态作为道具传递。我可以以某种方式将它包装<SomeComponent number={this.state.number} />}到回调或其他东西吗?
2021-03-17 11:25:51
更改组件的 state 或 props 会强制重新渲染,除非您已实现shouldComponentUpdate以其他方式告诉它。因此,一旦状态在 中发生变化<Main/>,它将重新渲染,并将新数字<SomeComponent/>作为新道具传递给如果您已经componentWillReceiveProps在 中实现<SomeComponent/>,您将在收到的道具中看到数字。这有意义吗?或者你想让我修改我的答案并更深入一点吗?
2021-03-20 11:25:51
如果你有时间/兴趣,你可以深入。我自己真的很感激。我的问题<SomeComponent/>是它不等待<Main/>重新渲染(我相信..)所以没有发送正确的状态值。我不知道如何实现您为此显示的回调。也许这解释得更好一点:jsfiddle.net/69z2wepo/13007
2021-03-25 11:25:51
你的问题是你正在提醒当前的道具<SomeComponent/>而不是新的道具该函数componentWillReceiveProps可以接受一个参数,nextProps,它包含所有收到的新道具。这是固定版本:jsfiddle.net/69z2wepo/13008请记住,在完成执行this.props之前不会改变componentWillReceiveProps
2021-03-26 11:25:51

setState 方法是异步的,因此在 console.log 调用中还没有新状态。您可以将回调作为第二个参数传递给 setState 并在那里调用 console.log。在这种情况下,该值将是正确的。

可能是因为在真正设置新状态之前触发了 console.log。

您应该使用该功能:

componentDidUpdate: function() {
    console.log(this.state.number);
}

每次状态更新时都会触发此函数。

希望能帮助到你

setState函数的文档中有一个有趣的注释:

setState() 不会立即改变 this.state 而是创建一个挂起的状态转换。调用此方法后访问 this.state 可能会返回现有值。

https://facebook.github.io/react/docs/component-api.html

为了在控制台使用打印状态号

this.setState({
        number: num
    },function(){console.log("but wrong here (previous number): " + this.state.number)})

代替

this.setState({
        number: num
    })
    console.log("but wrong here (previous number): " + this.state.number)

简而言之:使用 setState(function|object nextState[, function callback])