【问题标题】:React navigation drawer doesn't open consistently when dynamically setting drawer position using the Context API使用 Context API 动态设置抽屉位置时,React 导航抽屉无法始终打开
【发布时间】:2020-08-24 14:38:32
【问题描述】:

我正在尝试实现一个抽屉位置和内容可以动态更改的抽屉。

我有一个抽屉导航器,里面有一个堆栈导航器。堆栈导航器的标题有两个按钮。左侧按钮将drawerPosition 设置为"left" 并调用navigations.openDrawer(),右侧按钮将drawerPosition 设置为"right" 并调用navigation.openDrawer()

我当前的实现如下所示:

const Stack = createStackNavigator();
const Drawer = createDrawerNavigator();

const DrawerPositionContext = React.createContext([{}, () => {}]);

const DrawerPositionProvider = (props) => {
  const [drawerPosition, setDrawerPosition] = useState({});
  return (
    <DrawerPositionContext.Provider value={[drawerPosition, setDrawerPosition]}>
      {props.children}
    </DrawerPositionContext.Provider>
  );
};

function CustomDrawerContent(props) {
  return (
    <DrawerContentScrollView {...props}>
      {props.drawerPosition === 'left' ? (
        <DrawerItem label="Left" />
      ) : (
        <DrawerItem label="Right" />
      )}
    </DrawerContentScrollView>
  );
}

const Screen1 = () => {
  return <Text>Screen1</Text>;
};

const useDrawerPosition = () => {
  const [drawerPosition, setDrawerPosition] = React.useContext(
    DrawerPositionContext
  );

  return {
    drawerPosition,
    setDrawerPosition
  };
};

const DrawerNavigator = () => {
  const { drawerPosition, setDrawerPosition } = useDrawerPosition();

  return (
    <Drawer.Navigator
      drawerPosition={drawerPosition}
      drawerContent={(props) => (
        <CustomDrawerContent {...props} drawerPosition={drawerPosition} />
      )}
    >
      <Drawer.Screen name="stack navigator" component={StackNavigator} />
    </Drawer.Navigator>
  );
};

const StackNavigator = ({ navigation }) => {
  const { setDrawerPosition } = useDrawerPosition();

  return (
    <Stack.Navigator
      screenOptions={{
        headerLeft: () => (
          <Button
            title="left"
            onPress={() => {
              setDrawerPosition("left");
              navigation.openDrawer();
            }}
          />
        ),
        headerRight: () => (
          <Button
            title="right"
            onPress={() => {
              setDrawerPosition("right");
              navigation.openDrawer();
            }}
          />
        )
      }}
    >
      <Stack.Screen name="screen1" component={Screen1} />
    </Stack.Navigator>
  );
};

export default function App() {
  return (
    <DrawerPositionProvider>
      <NavigationContainer>
        <DrawerNavigator />
      </NavigationContainer>
    </DrawerPositionProvider>
  );
}

所以我使用 react context 来分享和更新当前抽屉位置。

我遇到的行为是打开左侧抽屉总是会正确打开抽屉,但打开右侧抽屉大部分时间都不会正确打开抽屉。我只看到背景阴影,而不是抽屉。

snack


我的第一个猜测是在抽屉打开之前上下文没有更新,但是将组件转换为基于类的组件并使用setState 回调给出了相同的结果,所以我不确定发生了什么在这里。

我知道做这样的事情的通常实现是创建以某种方式嵌套的两个抽屉,但是我尝试过的方法可以做到吗?


更新

我认为这是一个错误。问题似乎在Drawer.tsx (https://github.com/react-navigation/react-navigation/blob/main/packages/drawer/src/views/Drawer.tsx) 内部。

我对@9​​87654337@ (https://reactnative.dev/docs/animated) 不太熟悉,但我认为问题在于componentDidUpdate 中的这段代码:

if (prevProps.drawerPosition !== drawerPosition) {
  this.drawerPosition.setValue(
    drawerPosition === 'right' ? DIRECTION_RIGHT : DIRECTION_LEFT,
  );
}

【问题讨论】:

标签: reactjs react-native react-navigation react-context react-navigation-v5


【解决方案1】:

从搞乱你链接的零食,看起来上下文实际上已经更新了。仅当您从“右”切换到“左”时才会出现问题。 (这点我在inspector中看到的有点支持,但我没有深挖)。

请参阅此updated snack,它会在更新/冒泡时记录位置并默认为“正确”位置。如果你先点击右键,你可以看到它工作,但如果你点击左,它会中断。

总而言之,恕我直言,这是一个反应导航错误。这是一个似乎只出现在drawerType="front" 的问题,因此作为一种解决方法,您可以尝试将drawerType="back" 属性添加到Drawer.Navigator

【讨论】:

  • 是的,我认为你是对的。我认为node_modules/@react-navigation/drawer/src/views/Drawer.tsx 内部出了点问题。
  • 所有其他抽屉类型都可以工作,例如:向Drawer.Navigator 添加一个drawerType="slide" 道具可以解决它,但我不确定这就是你想要的。我可以向他们提出问题,但我不熟悉该项目。
  • 选择不同的抽屉类型实际上是一个很好的解决方法。如果您在回答中提到这一点,我会接受答案。 drawerType="back" 似乎与slide 一样工作得最好,按左抽屉按钮然后按右抽屉按钮后切换后内容消失。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-14
相关资源
最近更新 更多