Search code examples
reactjsreact-nativereact-componentreact-state

Check parent mounting status when updating state from a child component


In my react native 0.59.9 app, the App class has 2 states which may be updated by child components.

class App extends React.Component {

  state = {
    group_id: this.props.navigation.state.params.data.group_id,
    result: this.props.navigation.state.params.data.result,  
  };

 updateGroup = (group_id) => {
    console.log("In updateGroup : ", group_id);
    this.setState({group_id:group_id});
  };

  updateToken = (token) => {
    console.log("In updateToken : ", token);
    this.setState({result: token});
  };

const EventWithSelf = (props) => (<Event {...props} updateToken={this.updateToken}  />)
const GroupWithSelf = (props) => (<Group {...props} updateGroup={this.updateGroup} updateToken={this.updateToken} />);   
..........
}

Event and Group are child components which may update the App's state. In both updateGroup and updateToken, how does the app checkomg the mounting state of the App before executing setState? My concern is that the App may not be mounted when setState is executed. This will certainly throw out warnings.

UPDATE:

The updateToken is in componentDidMount in both Event and Group. updateGroup is triggged by click. Here is the code:

async _onPress(id) {
      let element = this.state.activeGroups;
      let element1 = element.find((e) => {
        console.log("e is ", e);
        return (e.id == id);
      });
      //save group_id clicked
      try {
        console.log("saved group id in Group : ", element1.id);
        await helper.setMyValue("group_id", element1.id.toString());
      } catch (err) {
        console.log("error in saving group_id to local disk", err);
      };
      this.props.updateGroup(element1.id); //<<<=== this causes "warning of no-op with updating unmounted component" in `Event` component.
      this.props.navigation.navigate("Event", {group_id:element1.id});
      return;
    }

Solution

  • Use componentDidMount lifecycle method to set a flag, and then pass this flag to the child components.

    Define the flag isMounted:

    constructor(props) {
            super(props);
            this.state = {
                isMounted: false,
            };
        }
    

    Set isMounted to true when component mounts.

    componentDidMount(){
        this.setState=({ isMounted: true })
    }
    

    And pass it down to the children.

    <Event {...props} isMounted={this.state.isMounted} updateToken={this.updateToken}  />
    

    Then, you can use isMounted flag to check the mounting status of the App before executing setState in the child components.