在React Native中从HOC内导航

时间:2019-06-13 10:20:30

标签: reactjs typescript react-native react-navigation higher-order-functions

我希望在我的应用程序的每个页面中添加一张支票。检查是否存在文件,然后将用户拉到页面。

我认为,HOC是执行此操作的一种方法(还有其他方法吗?)

我想出了这个

import React from "react";
import { NavigationScreenProp } from "react-navigation";
import RNFS from "react-native-fs";

interface MyComponentProps {
  navigation: NavigationScreenProp<any, any>;
}

interface MyComponentState {}

const importFileCheck = WrappedComponent => {
  class HOC extends React.Component<MyComponentProps, MyComponentState> {
    constructor(props) {
      super(props);

      this.props.navigation.addListener("didFocus", () => {
        RNFS.exists(
         ".\path\I\care\about.xml"
        ).then(exists => {
          if (exists) {
            this.props.navigation.navigate("Export");               
          }
        });
      });
    }

    render() {
      return <WrappedComponent {...this.props} />;
    }
  }

  return HOC;
};

export default importFileCheck;

运行页面时出现错误

  

TypeError:undefined不是一个对象(正在评估this.props.navigation.addListener)

所以我想导航“东西”没有正确通过

为完成任务,我像这样使用HOC

importFileCheck(App) 

App中已经有导航内容,可以在没有HOC的情况下使用。

进口

  

“反应”:“ 16.6.1”,
  “ react-native”:“ 0.57.7”,
   “反应导航”:“ 3.2.0”

热衷的其他细节:D

首先,我创建一个堆栈导航器,它是我应用程序中的所有页面

const appNav = createStackNavigator(
    {
        Calculator: {
            screen: Calculator,
            navigationOptions: { title: "Calculator" }
        },
   // more pages
);

export default createAppContainer(appNav);

App.tsx

这被“包装”在其他组件中

const WrappedStack = () => {
  return <RootStack screenProps={{ t: i18n.getFixedT() }} />;
};

const ReloadAppOnLanguageChange = translate("translation", {
  bindI18n: "languageChanged",
  bindStore: false
})(WrappedStack);

 class App extends React.Component {
  public render() {
    return (
      <I18nextProvider i18n={i18n}>
        <StyleProvider style={getTheme(material)}>
          <Provider
            ManureStore={ManureStore}
            SettingsStore={SettingsStore}
            FieldStore={FieldStore}
            CalculatorStore={CalculatorStore}
            FarmStore={FarmStore}
          >
            <ReloadAppOnLanguageChange />
          </Provider>
        </StyleProvider>
      </I18nextProvider>
    );
  }
}

最后我们用我的新HOC包装

export default importFileCheck(App) 

3 个答案:

答案 0 :(得分:1)

react-navigation中未提供有关如何使用组件的任何示例时,要弄清楚错误是什么并不容易。由于该问题与未通过导航道具有关,因此查看包含所有react-navigation详细信息的应用程序中如何使用HOC的更完整示例将很有帮助。

也就是说,也许您可​​以尝试使用withNavigation HOC来确保存在导航道具。它记录在这里: https://reactnavigation.org/docs/en/connecting-navigation-prop.html

答案 1 :(得分:0)

这打败了我(当应用程序从后台返回时,我想使用的导航事件不会触发)

这是我的解决方法

import React, { Component } from "react";
import { NavigationScreenProp } from "react-navigation";
import RNFS from "react-native-fs";
import { AppState } from "react-native";

interface Props {
  navigation: NavigationScreenProp<any, any>;
}

interface State {}

export default class ImportFileCheck extends Component<Props, State> {
  private _handleAppStateChange = nextAppState => {
    if (nextAppState === "active") {
      RNFS.exists(
        RNFS.DocumentDirectoryPath + "/Inbox/Import.json"
      ).then(exists => {
        if (exists) {
          this.props.navigation.navigate("Export");
        }
      });
    }
  };

  constructor(props) {
    super(props);
    AppState.addEventListener("change", this._handleAppStateChange);
  }

  public componentWillUnmount() {
    AppState.removeEventListener("change", this._handleAppStateChange);
  }
  public render() {
    return null;
  }
}

然后在每个页面文件return语句中我打一个<ImportFileCheck navigation={navigation} />

太可笑了!

答案 2 :(得分:0)

我们可以在版本5.x.x或更高版本中使用useNavigation的{​​{1}}钩子。

react-navigation

然后使用import { useNavigation } from '@react-navigation/native'; 初始化navigation

useNavigation

,然后使用const navigation = useNavigation(); 进行类似的导航操作。

navigation

希望这会对某人有所帮助。