我遇到了一个问题:我正在使用React / ReactNative + Flux构建我的第一个应用程序并获得此警告:
setState(...):只能更新已安装或安装的组件。这个 通常意味着您在未安装的组件上调用了setState()。这是 无操作。请检查未定义组件的代码。
高于我的代码:
>>> from django.conf import settings
>>> from django.contrib.auth import get_user_model
>>> settings.AUTH_USER_MODEL
>>> get_user_model().objects.all()
正如您所看到的,我正以非常简单的方式向您展示电影列表。现在显示一个更改视图的片段。当我将应用中的页面从显示电影的页面更改为显示信息时,我的问题就出现了。
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;
我在第一个片段的函数_onChange()中放了一个log()(因为问题存在于那里),当我改变页面时,多次调用该函数并获得上述警告。怎么解决它?我哪里做错了?谢谢!
答案 0 :(得分:0)
您为每个添加和删除事件侦听器函数提供了 new 函数实例。因此,删除将无法按预期工作,因为它针对不同的函数实例,并且更改事件仍然会触发事件。
我猜您正在将匿名函数传递给add / remove事件侦听器,以维护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
});
};
注意:以上内容依赖于提案中的class properties syntax,目前通过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);
};