Reputation: 2748
I am using mobX for my react native project. Please consider this store class:
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;
});
};
}
And this the react component:
@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>
)
}
}
From above it looks to me that:
Flat
component mounts, it call the method of the store setListOne()
.setListOne()
sets fetchingListOne
to true and makes an api call.fetchingListOne
is true, the ActivityIndicator displays, and in the ListHeaderComponent it should display true.fetchingListOne
to false.fetchingListOne
is set to false, ActivityIndicator should not display and in the ListHeaderComponent it should display false.However, this is not what's happening. Here when the setListOne()
method is called, after it sets the fetchingListOne
to true, the component does not react to the changes made after api call. And the ActivityIndicator keeps displaying and in ListHeaderComponent its displaying true.
What am I doing wrong here? Could you please help me. Thank you
Update
I have added a Text component before the FlatList. Adding a Text component or console logging inside the component class's render method does makes the FlatList react to the changes. I don't know why this is happening though.
Upvotes: 4
Views: 1468
Reputation: 4978
The problem you are running into here most probably, is that although Flat
is an observer
component, FlatList
is not (it's an built-in component after all). In this setup _renderFooter
and the others are part are rendered by render
of FlatList
, but not of FlatList
. Hence they are not part of the lifecycle of Flat, but of FlatList and as such are not tracked by Mobx
There are two ways to fix this, both pretty simple:
1) declare _renderItem
as observer component:
_renderItem = observer(({item}) =>
<Text style={styles.item}>{item.name}</Text>
);
2) use an inline anonymous Observer
component:
_renderItem = ({item}) =>
<Observer>{
() => <Text style={styles.item}>{item.name}</Text>}
</Observer>
Upvotes: 5