Search code examples
react-nativereact-native-router-flux

Have top right button click be recognized in presentational component using react native router flux


My app scenes use a container component which calls a presentational component.

I can create the top right button within the container component like this:

static right = () => {
  return (
    <TouchableOpacity onPress={() => buttonPressed()}>
      <Text style={styles.rightButtonText}>Done</Text>
    </TouchableOpacity>
  );
};

Now I am trying to have the top right button click be recognized by the presentational component (so it can save data).

I can communicate between the two by sending a function as a prop from the container component to the presentational component. And when that is called from the presentational component, it is called in the container component.

But I have found no way to make the static right function in the container component hear the click in the presentational component (to then take the appropriate action).

I tried these two solutions along with several others (including Action.refresh) but none work. I thought of using state, but I cannot access state or this. if I am using a static function. But removing static makes the button disappear altogether.

Thanks in advance for any help.


Solution

  • I've had a similar challenge in the past. The way I tackled was as follows (taken (mostly) directly from the codebase). Note that they are similar methods to the examples you provided, but perhaps this makes sense to you.

    • Container component

    Has an updateAccount function which handles the business logic. This is passed into the presentational component as a prop.

    • Presentational component

    Highlighting 2x specific functions from the presentational component:


    handleChange

    • On text input change, this function is triggered and data from the input is updated in state
    • When this is called, we know that the form has changed, so we want to show a 'save' button in the (react-native-router-flux) Navbar (which on tap, should trigger our container's updateAccount). So we call toggleSaveButton:

      handleChange = (name, val) => {
          this.setState({ [name]: val, formChanged: true }, this.toggleSaveButton);
      }
      

    toggleSaveButton

    • If this.state.formChanged is true, the form has changed so add the save button for the user to tap, otherwise hide it (eg. I might hide on form submit success)

      toggleSaveButton = () => {
        const config = this.state.formChanged
          ? { rightTitle: 'Save', onRight: () => this.props.updateAccount(this.state) }
          : { rightTitle: '', onRight: () => {} };
      
        Actions.refresh(config);
      };