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();