Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to update another tab`s state

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

like image 342
jojo Avatar asked Nov 03 '15 06:11

jojo


People also ask

How do you update your state?

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.

Is react state shared between tabs?

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.


1 Answers

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.

appContainer.js

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>
      );
    }
}

addData.js

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>
        );
    }


}

dataList.js

class PlayerList extends Component {
    constructor(props) {
        super(props);

    }


    render() {
        return (
            <View style={styles.container}>
                <Text>{this.props.dataLen}</Text>
            </View>
        );
    }
}
like image 71
Chris Geirman Avatar answered Oct 26 '22 07:10

Chris Geirman