I have two tabs in side a TabBarIOS.
First tab is offer function to add new item into AsyncStorage
Second tab display all item from AsyncStorage
But when i run my app, after adding a new item from First Tab, navigate to second tab i don`t see page re-render, i will need to do a Command+R then i see my new data.
One way to resolve the issue is to read asyncStorage in shouldComponentUpdate, but notice that shouldComponentUpdate will be called constantly by react. While i want to only force update the UI on demand.
So in react native, what is the right way to update state of another UI component?
sample app: https://drive.google.com/file/d/0B8kAIsj2xDnUMklIQmc0b3NiSVE/view?usp=sharing
To update our state, we use this. setState() and pass in an object. This object will get merged with the current state. When the state has been updated, our component re-renders automatically.
In the case of applications developed in ReactJS that work with state control using useState and useContext hooks, or even Redux in more complex scenarios, by default, the context is kept separately for each active tab in the user's browser.
Here's what I'm talking about. You will probably want to refactor this a bit once done, but in general here's how I think this would look in the end. I've still a lot to learn about using the lifecycle functions properly, and I'm not sure you'll need them now that I think about it.
I've essentially removed your NavigatorIOS. I think those were a mistake. Instead, I'm replacing them with the components, passing down the data as props, including a callback function for the button press. I've moved the addData function up a level.
class AppContainer extends Component {
constructor(props) {
super(props);
this.state = {
selectedTab: 'data-list',
dataLen: 0
}
AsyncStorage.getItem("all-data")
.then((data)=>{
if(!data)
{
data = "[]";
}
var dataObj = JSON.parse(data);
this.setState({
dataLen : dataObj.length
});
});
this.addData.bind(this);
}
addData() {
AsyncStorage.getItem("all-data")
.then((data)=>{
if(!data)
{
data = "[]";
}
var dataObj = JSON.parse(data);
dataObj.push({
val: Date.now()
});
AsyncStorage.setItem("all-data", JSON.stringify(dataObj));
this.setState({
dataLen: dataObj.length
});
});
}
render() {
return (
<TabBarIOS style={styles.container}>
<TabBarIOS.Item
title="Add Data"
selected={this.state.selectedTab == 'add-data'}
onPress={()=> this.setState({selectedTab: 'add-data'})}
>
<AddData onButtonPress={this.addData} dataLen={this.state.dataLen} />
</TabBarIOS.Item>
<TabBarIOS.Item
title="Data List"
selected={this.state.selectedTab == 'data-list'}
onPress={()=> this.setState({selectedTab: 'data-list'})}
badge={this.state.dataLen}
>
<DataList dataLen={this.state.dataLen} />
</TabBarIOS.Item>
</TabBarIOS>
);
}
}
This will simplify your sub-components significantly...
class AddData extends Component {
constructor(props) {
super(props);
}
render() {
return (
<View style={styles.container}>
<Text>{this.props.dataLen}</Text>
<TouchableHighlight
onPress={this.props.onButtonPress}
style={styles.button}>
<Text style={styles.buttonText}>Plus One</Text>
</TouchableHighlight>
</View>
);
}
}
class PlayerList extends Component {
constructor(props) {
super(props);
}
render() {
return (
<View style={styles.container}>
<Text>{this.props.dataLen}</Text>
</View>
);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With