首页 > 解决方案 > 包裹在 React.Component 中时不会调用 onStateChange

问题描述

我试图将 NavigationContainer 包装在 React 组件中以进行屏幕跟踪,这种方法在 V4 中运行良好,但在 V5 中失败了。后续问题是:是否可以将其包装在函数组件中而不是在反应组件中以具有使用钩子的能力?(必须承认我是比较新的反应)非常感谢任何帮助

应用程序.js

const Drawer = createDrawerNavigator();
function MyDrawer() {

  return (
    <Drawer.Navigator drawerType="front" drawerPosition="left">
      <Drawer.Screen name="Properties" component={PropertiesTabs} />
      <Drawer.Screen name="Profile" component={Profile} />
    </Drawer.Navigator>
  );
}

const AppContainer = function App() {
  return <NavigationContainer>{MyDrawer()}</NavigationContainer>;
}
export default with(AppContainer);

包装器.tsx

export function with(Component: any) {
        class PNDContainer extends React.Component {
        debounce;
        componentDidMount() {
            console.log('PND Mounted - First Time Screen');
        }
       componentWillUnmount() { }
       render() {
            return (<Component onStateChange={() => {
                console.log('Screen Changed Doesnt get Called !!!');
            }} />);
        }
    }
    return PNDContainer;
}

预期行为

环境
@react-navigation/native 5.7.0
react-native 0.61.5
节点 13.10.1
纱线 1.22.1

我可以理解为什么它不起作用,因为我传递了一个没有这样的道具onStateChange的函数元素,在 V4 CreatAppContainer返回了一个具有道具onNavigationStateChange
的组件 所以我想调用函数获取元素并“注入”我的onStateChange实施,但我认为反应不是那样工作的(它更像是命令式的方式,反应是一个声明性框架)那么什么是更好的方法呢?
所以我尝试在 chrome 中调试以查看onStateChange,没有运气......
我认为我误解了这些概念,我阅读了以下 React Function Components

编辑
现在唯一对我有用的解决方案是将我的组件包装在NavigationContainer
中并返回它

<NavigationContainer onStateChange={() => {console.log('ProbablynewScreen');}}>{Component()}
  </NavigationContainer>);

在那种情况下,我注意到发现抽屉并不是那么简单,抽屉的状态没有任何线索,如果我使用 Class 组件(不幸的是目前我必须)我没有钩子,那么我将如何发现抽屉打开/关闭?

标签: react-nativereact-navigation

解决方案


应用程序.js

const Drawer = createDrawerNavigator();
function MyDrawer(props) {
  return (
    <NavigationContainer onStateChange={props.onStateChange}>
      <Drawer.Navigator drawerType="front" drawerPosition="left">
        <Drawer.Screen name="Properties" component={PropertiesTabs} />
        <Drawer.Screen name="Profile" component={Profile} />
      </Drawer.Navigator>
    </NavigationContainer>
  )
};
export default with(MyDrawer)

与.tsx

export function with(Component: any) {
    class PNDContainer extends React.Component {
        child: any;
        componentDidMount() {
            //debugger;
            console.log('PND Mounted - First Time Screen');
        }
        componentWillUnmount() { }
        render() {
            debugger;
            return (<Component onStateChange={(state) => {
                debugger;
                console.log('Screen Changed');
            }} />)
        }
    }
    return PNDContainer;
}

感谢白熊


推荐阅读