简体   繁体   中英

React native: Give stack nav header access to a screen's state and another screen's function

Using stack navigator I have:

  • A custom header component SaveButton.js .
  • A form component AddItem.js .
  • A screen component that renders the data Food.js

Router.js

export const FoodStack = StackNavigator({
  Food: {
    screen: Food,
    navigationOptions: ({ navigation }) => ({
      title: 'Food',
      headerRight: <AddButton navigation={navigation} />, //navigates to AddItem
    })
  },
  AddItem: {
    screen: AddItem,
    navigationOptions: ({ navigation }) => ({
      title: 'Add Food',
      headerRight: <SaveButton navigation={navigation} />,
    })
  },
});

I need SaveButton.js to have access to AddItem.js state (contains user input) and a function in Food.js (retrieves data). That way, when save is clicked, I can grab state & store it and re-render data using the function.

SaveButton.js

export default class SaveButton extends Component {

onPress = async () => {
  const { goBack } = this.props.navigation;
  const { myData } = //Get myData from AddItem.js state
  const data = { myData };
  await store.push('array', data);
//Invoke getData in Food.js
  goBack();
};

render() {
    return (
        <TouchableOpacity
          onPress={this.onPress}
          style={styles.buttonStyle}
        >
          <Text style={styles.textStyle}>Save</Text>
        </TouchableOpacity>
      );
    }
}

Any help would be greatly appreciated, I've tried similar answers that involve passing data through navigation.state.params but I can't work out how to adapt for this instance.

Thanks

You can listen for props change in your component and set a specific parameter on header button press.

Example

export const FoodStack = StackNavigator({
  Food: {
    screen: Food,
    navigationOptions: ({ navigation }) => ({
      title: 'Food',
      headerRight: <AddButton navigation={navigation} />, //navigates to AddItem
    })
  },
  AddItem: {
    screen: AddItem,
    navigationOptions: ({ navigation }) => ({
      title: 'Add Food',
      headerRight: <SaveButton navigation={navigation} onPress={() => navigaion.setParams({saveItem: true}) />,
    })
  },
});

export default class SaveButton extends Component {

onPress = () => {
  if(this.props.onPress) this.props.onPress();
};

render() {
    return (
        <TouchableOpacity
          onPress={this.onPress}
          style={styles.buttonStyle}
        >
          <Text style={styles.textStyle}>Save</Text>
        </TouchableOpacity>
      );
    }
}

export default class AddItem extends Component {
  componentWillReceiveProps(nextProps) {
    const { params: prevParams } = this.props.navigation.state;
    const { params: nextParams } = nextProps.navigation.state;

    if(prevParams.saveItem !== nextParams.saveItem && nextParams.saveItem === true) {
      // I used a simple boolean value, you can pass an object with data to save
      this.saveItem();
    }
  }
  saveItem = () => {
    //run you save function here
    //then set parameter back to false
    this.props.navigation.setParams({saveItem: false});
    // then you can go back
    this.props.navigation.goBack();
  }
  render() {
    //...
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM