使用React Hooks从Prismic API获取数据

时间:2019-04-24 17:52:01

标签: javascript reactjs asynchronous react-hooks prismic.io

我正在尝试从Prismic无头CMS API查询数据,并使用React Hooks遇到问题。棱柱形API返回null,尽管我知道它已正确传递,因为我无需使用react钩子就可以成功查询它。

这里是我当前的组件代码。返回“无法读取null的属性'api'”。它没有到达“数据”控制台日志。

const Footer = ({ prismicCtx }) => {
  const [links, setLinks] = useState([]);

  useEffect(() => {
    const fetchLinks = async () => {
      const data = await prismicCtx.api.query([
        Prismic.Predicates.at('document.tags', [`${config.source}`]),
        Prismic.Predicates.at('document.type', 'footer'),
      ]);
      console.log('data:', data);
      setLinks(data.results[0].data);
    };

    fetchLinks();
  }, []);

  return (
    <div>
      <h1> Footer </h1>
    </div>
  );
};

export default Footer;

2 个答案:

答案 0 :(得分:1)

在最初的渲染prismicCtxnull的情况下,似乎只有这样,您才能在后续的渲染中收到更新后的值。解决方案显然是调用更改prismicCtx的效果,但是如果您只想在初始渲染时调用api,则需要跟踪是否较早调用了api,可以通过以下方法来实现使用useRef,并且如果prismicCtx不存在,也不需要将状态设置为空

const Footer = ({ prismicCtx }) => {
  const [links, setLinks] = useState([]);
  const isFirstCall = useRef(true);
  useEffect(() => {
   if(prismicCtx && isFirstCall.current) {
    const fetchLinks = async () => {
      const data = await prismicCtx.api.query([
        Prismic.Predicates.at('document.tags', [`${config.source}`]),
        Prismic.Predicates.at('document.type', 'footer'),
      ]);
      console.log('data:', data);
      setLinks(data.results[0].data);
    };
    fetchLinks();
    isFirstCall.current = false;
   }


  },[prismicCtx]);

  return (
    <div>
      <h1> Footer </h1>
    </div>
  );
};

export default Footer;

答案 1 :(得分:0)

想通了,我相信。 PrismicCTX正在树上更改,因此已切换为未定义。一个简单的if / else对其进行了修复,并使其仅在该属性更改时进行了更新。还是不确定最佳实践!

const Footer = ({ prismicCtx }) => {
  const [links, setLinks] = useState([]);

  useEffect(
    () => {
      const fetchLinks = async () => {
        const data = await prismicCtx.api.query([
          Prismic.Predicates.at('document.tags', [`${config.source}`]),
          Prismic.Predicates.at('document.type', 'footer'),
        ]);
        console.log('data:', data);
        setLinks(data.results[0].data);
      };
      if (prismicCtx) {
        fetchLinks();
      } else {
        setLinks([]);
      }
    },
    [prismicCtx]
  );

  return (
    <div>
      <h1> Footer </h1>
    </div>
  );
};

export default Footer;