Home > database >  Connecting two contexts return undefined values in the consumer context react hooks
Connecting two contexts return undefined values in the consumer context react hooks

Time:06-26

I really do not understand why this is not working, basically, I have a header component with its own context. On the other hand, I have a popOver component that goes inside the header, and this popOver also has its own context.

Now, there is a list of elements that are rendered inside the popOver, the user picks which elements to render, and such list needs to be rendered simultaneously in the header, for that reason I am trying to keep both contexts synchronized, the problem appears when I try to consume the header context inside the popOver context, the values consumed appear to be undefined.


const HeaderContext = createContext();

export const HeaderProvider = ({ children }) => {
  const [headChipList, setHeadChipList] = useState([]);
  const [isChipOpen, setIsChipOpen] = useState(false);

  useEffect(() => {
    if (headChipList.length) setIsChipOpen(true);
  }, [headChipList]);
  return (
    <HeaderContext.Provider value={{ headChipList, setHeadChipList, isChipOpen, setIsChipOpen }}>
      {children}
    </HeaderContext.Provider>
  );
};

export const useHeaderContext = () => {
  const context = useContext(HeaderContext);
  if (!context) throw new Error('useHeaderContext must be used within a HeaderProvider');
  return context;
};

As you can see at the end there's a custom hook that allows an easier consumption of the context and also is a safeguard in case the custom hook is called outside context, the popOver context follows this same pattern:

import React, { useState, useContext, createContext, useEffect } from 'react';

import { useHeaderContext } from '(...)/HeaderProvider';

const PopoverContext = createContext();

export const PopoverProvider = ({ children }) => {
  const { setHeadChipList, headChipList } = useHeaderContext;  // this guys are undefined
  const [menuValue, setMenuValue] = useState('Locations with Work Phases');
  const [parentId, setParentId] = useState('');
  const [chipList, setChipList] = useState([]);
  const [locations, setLocations] = useState([]);

  useEffect(() => setChipList([...headChipList]), [headChipList]);
  useEffect(() => setHeadChipList([...chipList]), [chipList, setHeadChipList]);

  return (
    <PopoverContext.Provider
      value={{
        menuValue,
        setMenuValue,
        chipList,
        setChipList,
        parentId,
        setParentId,
        locations,
        setLocations
      }}
    >
      {children}
    </PopoverContext.Provider>
  );
};

export const usePopover = () => {
  const context = useContext(PopoverContext);
  if (!context) throw new Error('usePopover must be used within a PopoverProvider');
  return context;
};

I would really appreciate any highlight about this error, hopefully, I will be able to learn how to avoid this type of error in the future

CodePudding user response:

You're not calling the useHeaderContext function. In PopoverProvider, change the line to

  const { setHeadChipList, headChipList } = useHeaderContext();
  • Related