【问题标题】:Navigating to other screens not working with programmatic routes导航到不适用于程序化路线的其他屏幕
【发布时间】:2021-05-18 12:02:33
【问题描述】:

我有一个 Routes 组件,它根据 user 状态返回 Stack.Screen 路由,或者根据来自上下文的 loading 状态返回加载屏幕。

由于某种原因,当调用navigation.nagivate 更改屏幕时,它只是重定向回initialRouteName 的任何位置。

我怀疑这是因为加载器没有返回任何路由,并且 navigation.navigate 调用在某处丢失,但我不确定。

MVCEhttps://codesandbox.io/s/morning-glitter-b8w5j?file=/src/App.js

Routes.js

function Routes() {
  const { loading } = useContext(AppContext);
  const { user } = useContext(AuthContext);

  if (loading) {
    return <Text>Loading</Text>;
  }

  return (
    <NavigationContainer>
      {user ? (
        <Stack.Navigator initialRouteName="Home">
          <Stack.Screen name="Home" component={HomeScreen} />
          <Stack.Screen name="Order" component={OrderScreen} />
        </Stack.Navigator>
      ) : (
        <Stack.Navigator initialRouteName="Login">
          <Stack.Screen name="Login" component={LoginScreen} />
        </Stack.Navigator>
      )}
    </NavigationContainer>
  );
}

OrderScreen.js(有问题的路线不起作用)

function OrderScreen({ order_id }) {
  const { order, getOrder } = useContext(OrderContext);
  useEffect(() => {
    getOrder(order_id);
  });
  return (
    <View>
      <Text>Order</Text>
      <Text>{order}</Text>
    </View>
  );
}

OrderProvider.js(调用getOrder

const OrderContext = createContext({});
function OrderProvider({ children }) {
  const [order, setOrder] = useState(null);
  const { setLoading } = useContext(AppContext);
  return (
    <OrderContext.Provider
      value={{
        order,
        setOrder,
        getOrder: (orderId) => {
          setLoading(true);
          setTimeout(() => {
            setOrder(orderId);
            setLoading(false);
          }, 1000);
        }
      }}
    >
      {children}
    </OrderContext.Provider>
  );
}

【问题讨论】:

    标签: javascript reactjs react-native react-navigation


    【解决方案1】:

    问题不在于导航,而在于您在上下文中的“加载”状态。

    因此,当您打开订单屏幕时,您在 AppContext 中将加载设置为 true,这会导致路由中的 NavigationContainer 重新呈现,从而重置导航状态。

    const OrderContext = createContext({});
    function OrderProvider({ children }) {
      const [order, setOrder] = useState(null);
      const [orderLoading, setOrderLoading] = useState(false);
      const { setLoading } = useContext(AppContext);
      return (
        <OrderContext.Provider
          value={{
            order,
            setOrder,
            orderLoading,
            getOrder: (orderId) => {
              setOrderLoading(true);
              setTimeout(() => {
                setOrder(orderId);
                setOrderLoading(false);
              }, 1000);
            }
          }}
        >
          {children}
        </OrderContext.Provider>
      );
    }
    

    您必须在订单上下文中加载才能解决此问题。而且重新渲染整个导航容器并不是一个好主意。

    小吃有一个工作示例,它只为订单屏幕加载

    https://snack.expo.io/@guruparan/9be728

    【讨论】:

    • 太棒了,谢谢。有没有办法保持全局加载状态,而不是为每个屏幕设置相同的加载机制?
    • 也许有一个 Modal 并将其显示在顶部,因为您重新渲染 NavigationContainer 它将失去状态,仍然就像每次重新渲染整个应用程序以加载项目,这不是我想要的会推荐
    • @BenFortune 这将用于高阶类,其中高阶类在需要时呈现加载器,否则呈现子类。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-22
    • 1970-01-01
    • 2020-09-24
    • 1970-01-01
    相关资源
    最近更新 更多