【问题标题】:Passing function as a param in react-navigation 5在 react-navigation 5 中将函数作为参数传递
【发布时间】:2020-05-23 15:38:57
【问题描述】:

注意:此查询适用于 react-navigation 5。

在反应导航 4 中,我们可以在导航时将函数作为参数传递,但在反应导航 5 中,它会引发有关序列化参数的警告。

基本上,我想做的是,从父屏幕导航到子屏幕,获取新值并更新父屏幕的状态。

以下是我目前正在实施的方式:

父屏幕

_onSelectCountry = (data) => {
    this.setState(data);
};
.
.
.

<TouchableOpacity
    style={ styles.countrySelector }
    activeOpacity={ 0.7 }
    onPress={ () => Navigation.navigate("CountrySelect",
        {
             onSelect: this._onSelectCountry,
             countryCode: this.state.country_code,
        })
    }
>
.
.
.
</TouchableOpacity> 

子屏幕

_onPress = (country, country_code, calling_code) => {
    const { navigation, route } = this.props;
    navigation.goBack();
    route.params.onSelect({
        country_name: country,
        country_code: country_code,
        calling_code: calling_code
    });
};

【问题讨论】:

  • 我正在应用完全相同的练习:/

标签: reactjs react-native react-navigation


【解决方案1】:

不建议通过 react native 导航参数传递回调,这可能会导致状态冻结(无法正确更新)。此处更好的解决方案是使用 EventEmitter,因此回调保留在 Screen1 中,并在 Screen2 发出事件时调用。

屏幕 1 代码:

import {DeviceEventEmitter} from "react-native"

DeviceEventEmitter.addListener("event.testEvent", (eventData) => 
callbackYouWantedToPass(eventData)));

屏幕2代码:

import {DeviceEventEmitter} from "react-native"

DeviceEventEmitter.emit("event.testEvent", {eventData});

useEffect(() => {
return () => {
    DeviceEventEmitter.removeAllListeners("event.mapMarkerSelected")
  };
}, []);

【讨论】:

  • 从“react-native”导入 {DeviceEventEmitter}
  • 屏幕1中的监听器最好也去掉
【解决方案2】:

有时您必须将函数作为参数传递给屏幕。

例如,您有第二个(独立的)NavigationContainer,它在 Modal 中呈现,当您在某个屏幕内按“完成”时,您必须隐藏(关闭)Modal 组件。

目前我看到的唯一解决方案是将所有内容都放在Context.Provider 中,然后在屏幕中使用Context.Consumer 调用Modal 的实例方法hide()

【讨论】:

    【解决方案3】:

    您可以使用navigate 将数据传回上一个屏幕,而不是在params 中传递onSelect 函数:

    // `CountrySelect` screen
    _onPress = (country, country_code, calling_code) => {
      const { navigation, route } = this.props;
      navigation.navigate('NameOfThePreviousScreen', {
        selection: {
          country_name: country,
          country_code: country_code,
          calling_code: calling_code
        }
      });
    };
    

    然后,您可以在您的第一个屏幕中处理此问题(componentDidUpdateuseEffect):

    componentDidUpdate(prevProps) {
      if (prevProps.route.params?.selection !== this.props.route.params?.selection) {
        const result = this.props.route.params?.selection;
    
        this._onSelectCountry(result);
      }
    }
    

    【讨论】:

    • this.props.route,params?.selection 中的,s 有意在componentDidUpdate 中吗?
    • 不,这是一个错字
    • 好的。我会试一试,让你知道。我很好奇的另一件事是,上面的 sn-p 如您所示,如果用户导航到子屏幕,选择一个将用户导航回父屏幕的国家/地区,然后用户按下硬件,将会发生什么返回键?他会被带回子屏幕吗?
    • 不,如果您已经访问过该屏幕,则导航操作类似于 goBack
    • 我还有一个问题,如果你有时间我可以在这里寻求帮助:stackoverflow.com/q/59799843/3697102
    猜你喜欢
    • 1970-01-01
    • 2020-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-17
    • 1970-01-01
    • 2019-11-07
    • 1970-01-01
    相关资源
    最近更新 更多