简体   繁体   中英

Passing state through navigation props

Can someone explain me why this doesn't work as i expect to.I'm trying to navigate from a screen to another using react navigation and i want to pass a value from state from a screen to another(I keep my value from state in Parent Component and also my 2 functions that changes the state value).When I navigate to my Child Component I pass value from state and both functions aswell.

The main problem is that i dont see any changes on the child screen when i triggeer the 2 functions, but when i go back to my parent screen, the changes had been made and they are visible on the screen.

I've tried to use this.forceUpdate() but it is still not working.

Any help?

This is my parrent component where i keep the state and the functions that change my state


import React from 'react';
import { Text, View, TouchableHighlight, Image, ScrollView, FlatList } from 'react-native';

export default class Parent extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      value: 2
    };
  }

  incrementValue = () => {
    this.setState(prevState => ({
      value: prevState.value + 1
    }));
  };

  decrementValue = () => {
    this.setState(prevState => ({
      value: prevState.value - 1
    }));
  };

  onPressButton = () => {
    this.props.navigation.navigate('Child', {
      value: this.state.value,
      incrementValue: this.incrementValue.bind(this),
      decrementValue: this.decrementValue.bind(this)
    });
  };

  render() {
    return (
      <View>
        <Text>parrent component</Text>
        <TouchableHighlight onPress={() => this.onPressButton()}>
          <Text style={{ color: 'red' }}>go to child</Text>
        </TouchableHighlight>
        <Text>state value : {this.state.value}</Text>
      </View>
    );
  }
}

And here this is my child component:


import React from 'react';
import { Text, View, TouchableHighlight, Image, ScrollView, FlatList } from 'react-native';

export default class Child extends React.Component {
  constructor(props) {
    super(props);
  }

  onPressIncrement = () => {
    this.props.navigation.state.params.incrementValue();
    this.forceUpdate();
  };

  onPressDecrement = () => {
    this.props.navigation.state.params.decrementValue();
    this.forceUpdate();
  };

  render() {
    const { navigation } = this.props;
    const value = navigation.getParam('value');
    alert(value);
    return (
      <View>
        <Text>Child component</Text>
        <Text>{value}</Text>
        <TouchableHighlight onPress={() => this.onPressIncrement()}>
          <Text>incrementValue</Text>
        </TouchableHighlight>
        <TouchableHighlight onPress={() => this.onPressDecrement()}>
          <Text>decrementValue</Text>
        </TouchableHighlight>
      </View>
    );
  }
}

It is normal. You just render your value prop only in first call of Child screen.

There is a lifecycle method named ComponentDidUpdate for your prop changes. It is triggered once one of your prop changes.

For example you can use like this in your Child Screen ,

componentDidUpdate(prevProps) {
  const value = navigation.getParam('value');
  console.log('prevProps', prevProps);
  console.log('new value', value);
}

You should see if value state changes in Parent Screen (which you passed as prop to your Child Screen ) then ComponentDidUpdate should triggered with new value.

Edit: After triggered componentDidUpdate and access new value. You can use setState for trigger render function.

constructor(props) {
    super(props);
    this.state = {
      value: navigation.getParam('value');
    }
  }

componentDidUpdate(prevProps) {
  const value = navigation.getParam('value');
  this.setState({ value });
}

render() {
    const { navigation } = this.props;
    return (
      <View>
        <Text>Child component</Text>
        <Text>{this.state.value}</Text>
        <TouchableHighlight onPress={() => this.onPressIncrement()}>
          <Text>incrementValue</Text>
        </TouchableHighlight>
        <TouchableHighlight onPress={() => this.onPressDecrement()}>
          <Text>decrementValue</Text>
        </TouchableHighlight>
      </View>
    );
  }

Hope it works.

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