在功能组件中使用 useSelector 时出现无效的钩子调用

时间:2021-03-26 07:37:57

标签: javascript reactjs react-redux react-hooks

我收到错误

<块引用>

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

  1. 您的 React 和渲染器版本可能不匹配(例如 React DOM)
  2. 你可能违反了钩子规则
  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>
}

1 个答案:

答案 0 :(得分:3)

您像普通函数一样调用 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>
}