繁体   English   中英

反应警告:setState(…)只能更新已安装或正在安装的组件

[英]React Warning: setState(…) Can only update a mounted or mounting component

我有一个问题:我正在使用React / ReactNative + Flux构建我的第一个应用程序,并且收到以下警告:

setState(...):只能更新已安装或正在安装的组件。 这通常意味着您在未安装的组件上调用了setState()。 这是无人值守。 请检查未定义组件的代码。

在我的代码上方:

class ListMovies extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            dataSource: new ListView.DataSource({rowHasChanged: (row1, row2) => row1 !== row2}),
            loaded: false
        };
    };

    componentDidMount() {
        ApiListMovies.getMovies();
        ListMoviesStore.addChangeListener(() => this._onChange());
    };

    componentWillUnmount() {
        ListMoviesStore.removeChangeListener(() => this._onChange());
    };

    _onChange() {
        console.log(this.state);
        this.setState({
            dataSource: this.state.dataSource.cloneWithRows(ListMoviesStore.getListMovies()),
            loaded: true
        });
    };

    render() {
        return (
            <ListView
                dataSource={this.state.dataSource}
                renderRow={this.renderMovie}
                style={styles.listView}
            />
        );
    }

    renderMovie(movie) {
        return (
            <View style={styles.container}>
                <Image
                    source={{uri: movie.posters.thumbnail}}
                    style={styles.thumbnail}
                />
                <View style={styles.rightContainer}>
                    <Text style={styles.title}>{movie.title}</Text>
                    <Text style={styles.year}>{movie.year}</Text>
                </View>
            </View>
        );
    }
}

module.exports = ListMovies;

如您所见,我以非常简单的方式向您显示了电影列表。 现在显示更改视图的代码段。 当我更改应用程序中的页面时,我的问题就从显示电影的页面更改为显示信息的页面。

class TabsView extends React.Component {

    //do stuff...

  renderContent() {
    switch (this.state.tab) {
      case 'List Movies':
        return <ListMoviesView/>;

      case 'Info':
        return <InfoView/>;

    }
  }

  render() {
    return (
        <View style={styles.content} key={this.state.tab}>
            {this.renderContent()}
        </View>
    );
  }
}

module.exports = TabsView;

我在第一个代码段的函数_onChange()中放置了一个log()(因为问题存在于其中),当我更改页面时,该函数被调用了几次,并获得上述警告。 如何解决? 我在哪里做错了? 谢谢!

您正在为每个添加删除事件侦听器函数提供一个新的函数实例。 因此,移除将无法按预期方式工作,因为它针对不同的函数实例,并且change事件仍会触发该事件。

我猜想您正在将匿名函数传递给添加/删除事件侦听器,以维护this.setState调用的范围。 您可以通过使用绑定到类属性的匿名函数来维护范围,然后只需在添加/删除调用中引用该属性,如下所示:

    componentDidMount() {
        ApiListMovies.getMovies();
        ListMoviesStore.addChangeListener(this._onChange);
    };

    componentWillUnmount() {
        ListMoviesStore.removeChangeListener(this._onChange);
    };

    // We use anonymous function bound to the class property, this
    // will maintain our scope.
    _onChange = () => {
        console.log(this.state);
        this.setState({
            dataSource: this.state.dataSource.cloneWithRows(ListMoviesStore.getListMovies()),
            loaded: true
        });
    };

注意:以上内容依赖于建议中的类属性语法 ,该语法目前已通过babel阶段1启用。 如果没有此功能,则可以在构造函数调用中创建函数。 像这样:

 class ListMovies extends React.Component {
   constructor(props) {
     this.state = {
      dataSource: new ListView.DataSource({rowHasChanged: (row1, row2) => row1 !== row2}),
      loaded: false
    };

    // We use anonymous function bound to the class property, this
    // will maintain our scope.
    this._onChange = () => {
        console.log(this.state);
        this.setState({
            dataSource: this.state.dataSource.cloneWithRows(ListMoviesStore.getListMovies()),
            loaded: true
        });
    };
   }

   componentDidMount() {
     ApiListMovies.getMovies();
     ListMoviesStore.addChangeListener(this._onChange);
   };

   componentWillUnmount() {
     ListMoviesStore.removeChangeListener(this._onChange);
   };

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM