4
import { createStackNavigator, createDrawerNavigator } from 'react-navigation'
import { Button, Text } from 'react-native'
import React, { Component } from 'react'

// Components

class Home extends Component {
  constructor(props) {
    super(props)
    this.state = {value: 1}
  }

  render() {
    return (<Text>{this.state.value}</Text>)
  }
}

class Settings extends Component {
  _press = function () {
    // Update Home's state here
  }

  render() {
    return (<Button title='Update Home' onPress={this._press.bind(this)}></Button>)
  }
}

// Navigation

const homeNavigator = createStackNavigator({
  HomeScreen: {screen: Home}
})

const settingsNavigator = createStackNavigator({
  SettingsScreen: {screen: Settings}
})

const drawerScreens = createDrawerNavigator({
  Home: homeNavigator,
  Settings: settingsNavigator
})

export default createStackNavigator({
  drawer: { screen: drawerScreens, navigationOptions: { header: null } }
})

I am trying to update the state of Home from my button in Settings while staying on the same screen (not using this.props.navigation.navigate), but after searching for hours and hours I just cannot figure out how to do it.

Is this even possible without something like Redux? I initially decided to use Redux to solve this problem, but when I found out they're dropping official support this season, I decided against it.

platizin
  • 792
  • 3
  • 10
  • 21

2 Answers2

3

This is possible by using NavigationActions.setParams as follows:

import { NavigationActions } from 'react-navigation';

const setParamsAction = NavigationActions.setParams({
  params: { value: 2 },
  key: 'screen-123',
});
this.props.navigation.dispatch(setParamsAction);

Note that you'll need to use the Home screen key. Then in your Home screen you'll need to listen to the changing navigation prop and act upon that change. This can be achieved by adding the componentWillRecieveProps React lifecycle event or with the getDerivedStateFromProps static method. Your params will be under this.props.navigation.state.params.

Take a look here

Asaf David
  • 3,167
  • 2
  • 22
  • 38
  • Ah this seems to work by just storing the keys in a map in another JS file, and importing that same map for every class - however `componentWillRecieveProps` never seems to trigger upon dispatching the action, or by going back to Home after the dispatch. Is there a reason why? – platizin Oct 28 '18 at 15:47
  • `setParams` should trigger `componentWillRecieveProps`, verify you're using the correct key. Going back will not trigger anything because the screen is still mounted all the time and no props have changed – Asaf David Oct 29 '18 at 09:21
0

In my case:

I created a state variable (called testValue) in my home screen module. Pass this variable to screen 2 during navigation. Modify it in screen 2 and then pass it back to home screen when navigating back.

Home screen: Here we create a variable testValue which is printed on the home screen. We also have a button that navigates to screen 2. We also pass the testValue variable through to screen 2.

function HomeScreen({ navigation }) {
  const [testValue, setTextFeed] = useState(0); 

  return (
    <View >
      <Text>{testValue}</Text>
      <Button
          onPress={() => {
            navigation.navigate("Screen 2", {
              value: testValue,
            });
          }}
      >
    </View>
  );
}


Screen 2: Here we retrieve the testValue variable that was passed from the home screen (it is stored in route argument). testValue is incremented by 5 units every time the user presses button1. The second button will navigate back to HomeScreen. Because we have passed testValue back to the home screen the value printed on the home screen will have been updated. Note: the home screen doesn't need the route argument.

function Screen2({ route, navigation }) {
  const { testValue} = route.params;
  const addFunc = () => {
    testValue += 5
  };

  return (
    <View >
      <Text>{testValue}</Text>

      //button1 this button increments testValue
      <Button
          onPress={() => addFunc()}
      >

      //button2 this button navigates to home screen
      <Button
          onPress={() => {
            navigation.navigate("HomeScreen", {
              value: testValue,
            });
          }}
      >
    </View>
  );
}

Michael
  • 56
  • 6