首页 > 解决方案 > 在功能组件中使用 useSelector 时挂钩调用无效

问题描述

我得到错误

错误:无效的挂钩调用。钩子只能在函数组件的主体内部调用。

  1. 你可能有不匹配的 React 版本和渲染器(例如 React DOM)
  2. 您可能违反了 Hooks 规则
  3. 你可能在同一个应用程序中拥有多个 React 副本

我不明白。我在useSelector()整个应用程序中都在使用,没有任何问题。在这个组件中使用它时,它会中断。这是为什么?

import { useSelector } from "react-redux";

const DrawerContent = (props) => {
  const someVar = useSelector((state) => state.foo.bar);
  return (
    <DrawerContentScrollView {...props}>
      <Foo>{someVar}</Foo>
      <DrawerItemList {...props}>
        <DrawerItem
          label="Kitten"
          onPress={() => props.navigation.navigate("Cat")}
        />
        <DrawerItem
          label="Doggo"
          onPress={() => props.navigation.navigate("Dog")}
        />
      </DrawerItemList>
    </DrawerContentScrollView>
  );
};

<DrawerContent />像这样使用

const DrawerNavigator = () => {
    return <Drawer.Navigator
        drawerContent={props => DrawerContent(props)}>
        <Drawer.Screen name='A' component={TabNavigator} />
        <Drawer.Screen name='B' component={AStack} />
        <Drawer.Screen name='C' component={BStack} />
    </Drawer.Navigator>
}

标签: javascriptreactjsreact-reduxreact-hooks

解决方案


您像普通函数一样调用 DrawerContent ,而不是将其用作标签。这样一来,DrawerContent 就不会有生命周期或状态,它只是一个普通的函数,返回东西。您需要使用 JSX 语法来调用它,然后 DrawerContent 将具有生命周期,您可以在那里使用Selector。

const DrawerNavigator = () => {
    return <Drawer.Navigator
        drawerContent={props => DrawerContent(props)}>  // This just call DrawerContent as a normal function with no life cycle and state
        <Drawer.Screen name='A' component={TabNavigator} />
        <Drawer.Screen name='B' component={AStack} />
        <Drawer.Screen name='C' component={BStack} />
    </Drawer.Navigator>
}

解决方案:

const DrawerNavigator = () => {
    return <Drawer.Navigator
        drawerContent={props => <DrawerContent {...props} />}>  // Now your component has life cycle
        <Drawer.Screen name='A' component={TabNavigator} />
        <Drawer.Screen name='B' component={AStack} />
        <Drawer.Screen name='C' component={BStack} />
    </Drawer.Navigator>
}

推荐阅读