似乎是个小问题.

我有一个应用程序,人们可以通过"stripe"订阅.希望根据订阅提供对几个URL的访问,否则会将它们带回"配置文件"页面.

有几件事不管用.

  1. 获取subscription的Firebase查询未给出订阅结果.不知怎的,onSnapShot什么也拿不到.可能是因为UID在页面呈现开始时为空.

  2. 条件运算符on不起作用.不确定这件事有什么问题.



function PaidRoutes(props) {


  const [subscription, setSubscription] = useState([]);
  const [loading, setLoading] = useState(false);

  useEffect(() => {
    const unsub = auth.onAuthStateChanged((authObject) => {
      unsub();
      if (authObject) {
        setLoading(true);
        const uid = auth.currentUser?.uid;
        console.log('UID ==>', uid);
        let docRef = query(collection(db, 'customers', uid, 'subscription'));
        console.log('DOC REF ==> ', docRef);
        onSnapshot(docRef, (snap) => {
          snap.forEach((doc) => {
            console.log('Role of Subscription', doc.data().role);
            setSubscription(doc.data().role);
          });
        });
      } else {
        console.log('not logged in');
        setLoading(false);
      }
    });
    return () => {
      unsub();
    };
  }, []);



  return (
    <Route
      {...props}
      render={(props) =>
        subscription ? (
          <Component {...props} />
        ) : (
          <Redirect to='/profileScreen' />
        )
      }
    />
  );

感谢Drew的 comments .react-router-dom的安装版本是5.2.0

推荐答案

Issue(s)

我在PaidRoute代码中看到的潜在问题:

  1. 在身份验证状态处理程序中调用unsubscribe函数,这可能会允许身份验证判断在初始身份验证更改时工作一次,但随后将取消订阅并停止工作,直到组件重新装载.
  2. loading状态最初为false,因此在初始渲染中基于它的任何判断都不会执行您想要的操作.loading也不用于延迟条件渲染.
  3. subscription状态最初是一个空数组,它仍然是真实的,因此条件逻辑判断它可能会允许访问受保护的路由,而不管任何身份验证状态.

Solution

  1. 不要在回调中从auth change listener取消订阅.
  2. loading initially true开始处理初始渲染周期.有条件地呈现null或某些加载指示符.
  3. 从空subscription状态开始.

代码:

function PaidRoutes(props) {
  const [subscription, setSubscription] = useState(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    const unsubscribe = auth.onAuthStateChanged((authObject) => {
      if (authObject) {
        setLoading(true);
        const uid = auth.currentUser?.uid;
        console.log('UID ==>', uid);
        const docRef = query(collection(db, 'customers', uid, 'subscription'));
        console.log('DOC REF ==> ', docRef);
        onSnapshot(docRef, (snap) => {
          snap.forEach((doc) => {
            console.log('Role of Subscription', doc.data().role);
            setSubscription(doc.data().role);
          });
        });
      } else {
        console.log('not logged in');
        setSubscription(null); // <-- reset auth state
      }
      setLoading(false); // <-- clear loading state outside if-else
    });

    return unsubscribe;
  }, []);

  if (loading) {
    return null; // or loading indicator, spinner, etc...
  }

  return subscription ? (
    <Route {...props} />
  ) : (
    <Redirect to='/profileScreen' />
  );
}

Javascript相关问答推荐

使用JavaScript在ionic Web应用程序中更新.pane和.view的背景 colored颜色

materialized - activeIndex返回-1

单击子元素时关闭父元素(JS)

处理时间和字符串时MySQL表中显示的日期无效

为什么我的导航条打开状态没有在窗口addeventlistener(Reaction Js)中更新?

第二次更新文本输入字段后,Reaction崩溃

为什么JPG图像不能在VITE中导入以进行react ?

使用Ace编辑器对子组件实例的native-element 进行Angular 获取时面临的问题

第一项杀死下一项,直到数组长度在javascript中等于1

try 将Redux工具包与MUI ToggleButtonGroup组件一起使用时出错

在表单集中保存更改时删除';禁用';

无法重定向到Next.js中的动态URL

重新呈现-react -筛选数据过多

在JavaScript中,有没有一种方法可以迭代字符串的词法标记?

如果我的列有条件,我如何呈现图标?

如何在TransformControls模式下只保留箭头进行翻译?

P5play SecurityError:无法从';窗口';读取命名属性';Add';:阻止具有源的帧访问跨源帧

有没有办法在R中创建一张具有多个色标的热图?

扩散运算符未按预期工作,引发语法错误

观察子组件中的@Output事件emits 器?