反应导航“焦点”事件侦听器未使用更新的值

时间:2020-04-17 05:44:11

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

我遇到了反应导航事件监听器的问题!

逻辑:每当用户进入我的本机应用程序的购物车屏幕时,我都希望获取购物车详细信息。为了决定是否获取购物车详细信息,我在商店中检查了购物车ID。如果cart id为null,则表示尚未创建购物车,因此请关闭加载程序,不要获取购物车详细信息。另一方面,如果商店中有购物车ID,请获取购物车详细信息。

场景1:第一次,如果商店中没有购物车ID时我进入购物车屏幕,它将不会加载购物车详细信息:一切都很好!但是,在随后访问购物车屏幕后,即使商店中有购物车ID,它也不会获取购物车详细信息。

方案2:第一次,如果商店中存在购物车ID时我访问购物车屏幕,则这次将在下次访问时也获取购物车详细信息。

可能的问题:因此,问题似乎在于,事件侦听器将使用首次运行时将提供的购物车值,而不考虑更新后的值!请指出正确的方向!

useEffect(()=>{
    let cartId = context.store.cartReducer.cart.id;
    const unsubscribe = props.navigation.addListener('focus', () => {
        if(cartId) {
            setIsDetailsLoading(true);
            fetchCartDetails(context.dispatch, {cartId: cartId});
        } else {
            setIsDetailsLoading(false);
        }
    });
    return unsubscribe;
}, []);

解决方案

所以最终我弄清楚了,如果您使用的值可能会发生变化,则必须将其添加到以前为空的数组(useEffect挂钩的第二个参数)中。

所以代码看起来像...

useEffect(()=>{
    let cartId = context.store.cartReducer.cart.id;
    const unsubscribe = props.navigation.addListener('focus', () => {
        if(cartId) {
            setIsDetailsLoading(true);
            fetchCartDetails(context.dispatch, {cartId: cartId});
        } else {
            setIsDetailsLoading(false);
        }
    });
    return unsubscribe;
}, [context.store.cartReducer.cart.id]);

2 个答案:

答案 0 :(得分:1)

对于反应导航4.x尝试使用“ willFocus”而不是“ focus”

useEffect(()=>{
    let cartId = context.store.cartReducer.cart.id;
    const unsubscribe = props.navigation.addListener('willFocus', () => {
        if(cartId) {
            setIsDetailsLoading(true);
            fetchCartDetails(context.dispatch, {cartId: cartId});
        } else {
            setIsDetailsLoading(false);
        }
    });
    return unsubscribe;
}, []);

答案 1 :(得分:0)

在React Navigation v5.x中,您应该使用“导航生命周期”

Documentation here

文档示例:

import { useFocusEffect } from '@react-navigation/native';

function Profile() {
  useFocusEffect(
    React.useCallback(() => {
      // Do something when the screen is focused

      return () => {
        // Do something when the screen is unfocused
        // Useful for cleanup functions
      };
    }, [])
  );

  return <ProfileContent />;
}