首页 > 解决方案 > 如何在 react-firebase-hooks 中实现缓存?

问题描述

我一直在尝试在react-firebase-hooks中实现缓存但收到此错误

不能在回调中调用 React Hook “useCollectionDataOnce”。必须在 React 函数组件或自定义 React Hook 函数中调用 React Hooks

我知道我是有条件地调用它,但还有其他方法可以做到这一点吗?顺便说一句,我正在遵循这个来实现缓存。

const [randomQuestions, setRandomQuestions] = React.useState([]);
const cachedData = localStorage.getItem("randomQuestions");
React.useEffect(() => {
    if (cachedData) {
      setRandomQuestions(JSON.parse(cachedData));
    } else {
      let [values, loading, error] = useCollectionDataOnce(
        db
          .collection("questions")
          .where("tags", "array-contains-any", tags.length ? tags : [""])
          .limit(10),
        { idField: "id" }
      );
    }
    if (values) {
      localStorage.setItem("randomQuestions", JSON.stringify(values));
      setRandomQuestions(values);
    }
  });

在代码中,我试图检查是否cachedData已经存在。如果没有,则查询并获取数据。如果是,则设置randomQuestions.

标签: javascriptreactjsfirebasegoogle-cloud-firestore

解决方案


React Hooks 不能位于此处所述的条件中。您应该在 if/else 语句之外使用它。

查看文档useCollectionDataOnce我发现函数的变量是可选的,因此您可以定义一个辅助变量,根据您的需要填充在 if/else 语句中,并将其传递给useCollectionDataOnce.

const [randomQuestions, setRandomQuestions] = React.useState([]);
const cachedData = localStorage.getItem("randomQuestions");
React.useEffect(() => {
    var query = "";
    if (cachedData) {
          setRandomQuestions(JSON.parse(cachedData));
          query = "";
    } else {
          query = db
              .collection("questions")
              .where("tags", "array-contains-any", tags.length ? tags : [""])
              .limit(10),
            { idField: "id" };  
    }
    let [values, loading, error] = useCollectionDataOnce(query); 
    if (values) {
      localStorage.setItem("randomQuestions", JSON.stringify(values));
      setRandomQuestions(values);
    }
  });

推荐阅读