【问题标题】:Strange Reactjs setState behaviour奇怪的 Reactjs setState 行为
【发布时间】:2015-10-16 13:32:13
【问题描述】:

Reactjs 的 setState 函数有一个非常奇怪的问题。 它似乎希望我以一种非常具体的方式来构建我的代码片段,否则它将无法工作。 我不知道为什么这会导致问题,因为这两种结构对我来说看起来相同,但行为方式不同。

我正在使用 Browserify 和 Babelify 进行编译,并使用 gulp-uglify 来缩小我的代码。可能是这些构建步骤中的一个或组合导致了问题,但我不知道是哪个(因此我也不知道是否以及在哪里提交问题)

这是我的代码的相关部分:

export default class VideoAppScreen extends React.Component {
    constructor( props ) {
        super( props );
        this.state = { 
            playing: 0,
            playlist: []
        };
    }

    addVideo( video ) {
        this.setState( ( previousState ) => {
            return {playlist: previousState.playlist.push( video )};
        });
    }

    onEnd( event ) {
        console.log( "onEnd", event, this.state );
        this.setState( ( previousState ) => {
            return {playing: previousState.playing + 1};
        });
    }   

    render() {
        // stuff
    }
}

如您所见,setState 块的格式如下:

this.setState( ( previousState ) => {
    return {item: value};
});

像这样 addVideo 方法会导致错误:Uncaught TypeError: t.playlist.push is not a function

如果我将块更改为这样:

this.setState( ( previousState ) => {item: value} );

addVideo 方法有效,但 onEnd 方法停止工作(不会导致错误,它只是不更新​​状态)

我不明白为什么它们的工作方式不同...出于格式化目的,我希望它们都具有相同的样式,但似乎它们仅在以任何一种样式格式化时才起作用。

【问题讨论】:

    标签: javascript reactjs browserify babeljs gulp-uglify


    【解决方案1】:

    我的猜测是previousStateundefined,并且您的问题不是由间距引起的。

    react's component lifecycle doc 中所述,之前的状态只能在特定函数中访问:

    • shouldComponentUpdate(nextProps, nextState),
    • componentWillUpdate(nextProps, nextState)
    • componentDidUpdate(prevProps, prevState)

    因此,如果您在其他时间调用您的函数,previousState 将是未定义的。

    【讨论】:

    • 正如您在setState documentation 中看到的,您可以使用函数(或对象 nextState)作为 setState 的参数,该函数使用“previousState”(或 currentState)调用,并且必须返回下一个状态。此外,当格式化相同时,只有一个功能会遇到问题,另一个会正常工作,这告诉我应该正确使用它(否则两者都不起作用)但其他地方有问题。
    • 你是对的。错过了。另一个可能的问题:通过调用previousState.playlist.push() 我想你也直接更新了previousState,这反应不喜欢。这可能是这里的问题吗?
    • Mhhh 它可能是......但是当我像这样构造我的代码时它确实工作this.setState( ( previousState ) => {playlist: previousState.playlist.push( video )} );我将尝试从我的构建过程中删除 uglify 步骤并调试捆绑文件
    • 解决了... Array.prototype.push() 的行为与我的预期不同。
    【解决方案2】:

    因此,当我们的Array.prototype.push() 的行为与我预期的不同时,它返回数组的长度,其中添加了新元素see mdn documentation

    我基本上是将我的播放列表从[] 重置为1,当然数字没有推送功能...

    我不知道为什么其他格式的格式确实按预期运行... babelified 代码似乎不应该工作(当我将另一个函数更改为看起来相同时也不起作用)

    【讨论】:

      猜你喜欢
      • 2022-01-18
      • 2021-03-02
      • 1970-01-01
      • 2021-08-01
      • 2019-08-03
      • 1970-01-01
      • 2020-02-03
      • 1970-01-01
      • 2015-09-27
      相关资源
      最近更新 更多