Can I subscribe to this.props.navigation.state.params?

Viewed 340

I am wonder if in screenA I have an object data = {} that will be changed dynamically, can I receive changes in screenB by just sending this props from screenA through this.props.navigation.navigate('screenB', {data})?

And in screenB to have a componentWillReceiveProps(nextProps) to get this changes through something like nextProps.navigation.state.param.data

Or there is a way to achieve this?

2 Answers

It is easy, just as you said: send some data navigation.navigate('screenB', { data }) and receive it in the screenB as navigation.state.params.data.

I agree with @FurkanO you probably show use Redux instead to control all the state of your app, but for simple stuff I think isn't necessary!

I made a simple snack demo to show you: snack.expo.io/@abranhe/stackoverflow-56671202

Here some code to follow up:

Home Screen

class HomeScreen extends Component {
  state = {
    colors: ['red', 'blue', 'green'],
  };

  render() {
    return (
      <View>
        {this.state.colors.map(color => {
            return <Text>{color}</Text>;
        })}
        <View>
          <Text>Details Screen</Text>
          <Button
            title="Go to Details"
            onPress={() => this.props.navigation.navigate('Details', { colors: this.state.colors })}
          />
        </View>
      </View>
    );
  }
}

Details Screen

class DetailsScreen extends Component {
  state = {
    colors: [],
  };

  componentWillMount() {
    this.setState({ colors: this.props.navigation.state.params.colors });
  }

  render() {
    return (
      <View>
        {this.state.colors.map(color => {
            return <Text>{color}</Text>;
        })}
        <Text>Details Screen</Text>
      </View>
    );
  }
}

Update

The question's author requested an update to add a setTimeout() to see the exact moment when the data is on the other screen, so it will look like this:

componentWillMount() {
    setTimeout(() => {
      this.setState({ colors: this.props.navigation.state.params.colors });
    }, 3000);
}

You can use onWillFocus of NavigationEvents, which fires whenever the screen is navigated to.

_willFocus = () => {
  const { navigation } = this.props
  const data = navigation.getParam('data', null)
  if (data !== null) {
    /* do something */
  }
}

/* ... */

render () {
  return (
    <View>
      <NavigationEvents onWillFocus={_willFocus()}
    </View>
  )
}
Related