Pass Props StackNavigator

心不动则不痛 提交于 2020-05-26 10:51:06

问题


i try to pass props on stacknavigator, here my code

const MainCart = StackNavigator({
  Cart: {
    screen: CartScreen
  },
  Checkout: {
    screen: COScreen
  }

  /* how to pass 'myprops' in this area? */

});


export default class ReactNative_RefreshControl extends Component {

  constructor(props) {
    super(props)
  }

  render() {
    console.log('ReactNative_RefreshControl this.props.myparam : ' + this.props.myparam);
    return <MainCart myprops = {
      this.props.myparam
    }
    />;

    //https://reactnavigation.org/docs/navigators/stack#Navigator-Props
  }


}

how to pass 'myprops' on StackNavigator area?

thanks


回答1:


React Navigation < 5

If you want to pass props in that place you have to use it like this.

const MainCart = StackNavigator({
 Cart: {
    screen: props=> <CartScreen {...props} screenProps={other required prop}>
 },
 Checkout: {
    screen: COScreen
 }

If you want to pass props when navigating the solution by Sagar Chavada is useful

React Navigation - 5

You have to either use React Context(recommended) or a render callback to solve this. Documentation link

Below example shows how to do with React Context

In your parent of the navigator file create a context

<AppContext.Provider value={other required prop}>
   <YourNavigator/>
</AppContext.Provider>

In your navigator file

const YourNavigator = () => (
  <AppStack.Navigator>
     <AppScreen.Screen name={"routeName"} component={AppContextWrapper}/>
  </AppStack.Navigator>

const AppContextWrapper = ({ navigation, route }) => (
  <AppContext.Consumer>
    {(other required prop) => (
       <YourScreenComponent {...other required prop}/>
    )}
  </AppContext.Consumer>
);

another easy (not recommended) - Callback method

<Stack.Screen name="Home">
  {props => <HomeScreen {...props} extraData={someData} />}
</Stack.Screen>

Note: By default, React Navigation applies optimizations to screen components to prevent unnecessary renders. Using a render callback removes those optimizations. So if you use a render callback, you'll need to ensure that you use React.memo or React.PureComponent for your screen components to avoid performance issues.




回答2:


in your click event do like this:

    onPressed(movie){
        this.props.navigation.navigate(
          'screen',
          {movie: movie}
        });
      }

<TouchableHighlight onPress={() => this.onPressed(movie)}>

and in other screen you can set like this:

export default class NavigateTo extends Component {
  constructor(props){
    super(props);

    this.state = {
        name: this.props.navigation.state.params.movie.title,
        year: this.props.navigation.state.params.movie.year
    }
  }

movie is a json object that contain title, year, release date, earning, poster, etc..

this one is for old navigation:

onPressed(movie){
    this.props.navigator.push({
      id:'page2',
      movie: movie
    });
  }

and in second screen:

this.state = {
        name: this.props.movie.title,
        email: this.props.movie.year
    }

now you can see the difference

if this not work than try like this

<Button title="Second" onPress={() => navigate("MainCart",{},
  {
    type: "Navigate",
    routeName: "Checkout",
    params: {name:"Jo"}
  }
)} />

check this for nested stack navigation https://github.com/react-community/react-navigation/issues/143




回答3:


In my case I wanted to pass a function to show toast with conte for every component, I ended up achieving it by using screenProps and overriding each component:

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

showToast = (text) => {
  this.refs.toast.show(text, DURATION.FOREVER);
};

render() {
  return <Provider store={store}>
    <View style={styles.wrapper}>[
      <MyAppNavigator showToast={this.showToast}/>,
      <Toast ref="toast"/>
      ]
    </View>
  </Provider>;
  }
}

const styles = StyleSheet.create({
  wrapper: {
    flex: 1
  }
});


const createNavigator = (screenProps) => {
  const toastWrapper = (Component, props, screenProps) => {
    return <Component {...props} screenProps={screenProps}/>
  };
  return createStackNavigator({
    login: {
      screen: props => toastWrapper(LoginView, props, screenProps),
      navigationOptions: () => {
        return {header: null}
      }
    },
    map: {
      screen: props => toastWrapper(FieldMap, props, screenProps),
      navigationOptions: () => ({
        title: 'Map'
      })
    }
  })
};

const MyAppNavigator = (props) => {
  const AppNavigator = createNavigator(props);
  return <AppNavigator/>
};

Then from my component:

this.props.screenProps.showToast("Logging you in");



回答4:


I need to send props from main component to StackNavigator and then passing down to it's component, I used screenProps to do that.

Your main function should look like this:

render() {
    return <MainCart screenProps={this.props.params}
    />;
  }

After that in navigator screen you can access it like this:

this.props.screenProps.params



回答5:


My previous answer holds if you are trying to access the app level from a navigation view, however, if you want to simply change the header or something like that you don't have to pass the params to your navigator.

A little bit of React magic:

export default class ReactNative_RefreshControl extends Component {
  constructor(props) {
    super(props)
  }

  //this function will override the navigation options specified in MainCart component
  static navigationOptions = ({navigation}) => {
    return {
      headerTitle: navigation.state.params.name,
      headerRight: <Button onPress={navigation.state.params.onClick}/>
    };
  };

  componentDidMount() {
    this.props.navigation.setParams({
      name: "name",
      onClick: this.onClick
    });
  }
  ...
}



回答6:


For those who are looking for React Navigation 5

<Stack.Navigator initialRouteName="LoginScreen" headerMode="none">
 <Stack.Screen name="LoginScreen" component={LoginScreen} initialParams={{'key':'value'}} />
 <Stack.Screen name="CodeVerificationScreen" component={CodeVerificationScreen} initialParams={{'key':'value'}} />
</Stack.Navigator>

You can receive initial params in login.js

console.log(this.props.route.params.key)


来源:https://stackoverflow.com/questions/47027401/pass-props-stacknavigator

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!