我正在使用 mobX 作为我的反应原生项目。请考虑这个商店类:
class Birds {
@observable listOne = [];
@observable fetchingListOne = false;
@observable fetchErrorOne = '';
@action setListOne = () => {
this.fetchingListOne = true;
api.getList()
.then((data) => {
this.listOne.replace(data);
this.fetchingListOne = false;
})
.catch((error) => {
this.fetchingListOne = false;
this.fetchErrorOne = error;
});
};
}
这就是反应成分:
@inject('BirdStore') @observer
export default class Flat extends React.Component {
componentDidMount() {
this.props.BirdStore.setListOne();
}
_renderHeader = () => {
return <Text style={styles.listHeaderText}>
Hello {this.props.BirdStore.listOne.length} is {this.props.BirdStore.fetchingListOne.toString()}
</Text>;
};
_renderItem = ({item}) => {
return <Text style={styles.item}>{item.name}</Text>
};
_renderFooter = () => {
if (this.props.BirdStore.fetchingListOne) {
return <ActivityIndicator/>
}
else {
return null
}
};
render() {
const dataSource = this.props.BirdStore.listOne.slice();
return (
<View style={styles.container}>
<Text>Fetching: {this.props.BirdStore.fetchingListOne.toString()}</Text>
<FlatList
style={styles.listContainer}
ListHeaderComponent={this._renderHeader}
data={dataSource}
renderItem={this._renderItem}
keyExtractor={(item, i) => item.id}
ListFooterComponent={this._renderFooter}
/>
</View>
)
}
}
从上面看,我认为:
Flat
组件安装时,它会调用商店setListOne()
的方法。setListOne()
将fetchingListOne
设为true并拨打api电话。fetchingListOne
为真时, ActivityIndicator 显示,而 ListHeaderComponent 则显示为true。fetchingListOne
设置为false。fetchingListOne
设置为false, ActivityIndicator 不应显示,而 ListHeaderComponent 中应显示false。但是,这不是发生的事情。这里调用setListOne()
方法时,在将fetchingListOne
设置为true后,组件不会对api调用后所做的更改做出反应。并且 ActivityIndicator 一直显示并在 ListHeaderComponent 中显示为true。
我在这里做错了什么?请你帮助我好吗。谢谢
更新
我在FlatList之前添加了一个Text组件。在组件类的render方法中添加Text组件或控制台日志记录会使FlatList对更改做出反应。我不知道为什么会发生这种情况。
答案 0 :(得分:5)
您最常遇到的问题是虽然Flat
是observer
组件,但FlatList
不是(它毕竟是内置组件) )。在此设置_renderFooter
中,其他部分由render
的{{1}}呈现,而不是FlatList
呈现。因此,它们不是Flat的生命周期的一部分,而是FlatList的生命周期,因此不会被Mobx跟踪
有两种解决方法,非常简单:
1)将FlatList
声明为观察者组件:
_renderItem
2)使用内联匿名_renderItem = observer(({item}) =>
<Text style={styles.item}>{item.name}</Text>
);
组件:
Observer