0

我正在尝试从 Prismic headless CMS API 查询数据,并在使用 React Hooks 时遇到问题。棱镜 API 返回 null,尽管我知道它被正确传递,因为我可以在不使用反应钩子的情况下成功查询它。

这是我当前的组件代码。它返回“无法读取 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;
4

2 回答 2

1

似乎是在初始渲染时prismicCtx并且null仅在后续渲染时才收到更新值的情况。解决方案显然是调用更改的效果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;
于 2019-04-24T18:44:42.007 回答
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;
于 2019-04-24T18:16:18.750 回答