0

I'm trying to query data from the Prismic headless CMS API and running into problems using React Hooks. The prismic API is returning null, though I know its being passed down correctly as I can query it successfully without using react hooks.

Heres my current compontent code. Its returning "cannot read property 'api' of null". It doesn't reach the 'data' console log.

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;
geeberry
  • 617
  • 2
  • 10
  • 17

2 Answers2

1

It seems to be a case where on initial render prismicCtx is null and only on the subsequent render you receive the updated value. The solution is obviously to call the effect on change of prismicCtx, but you if you just want to call the api on initial render you would need to keep track of whether you called the api earlier or not which you can achieve by using useRef and also you don't need to set the state as empty if prismicCtx doesn't exist

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;
Shubham Khatri
  • 270,417
  • 55
  • 406
  • 400
0

Figured it out, I beleive. PrismicCTX was being changed up the tree so it was switching to undefinded. A simple if/else fixed it and making it so it only updated on that prop change. Still not sure if best practice though!

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;
geeberry
  • 617
  • 2
  • 10
  • 17