skip to Main Content

My context provider allows me to take values from it and provide them to Navbar and update if a person clicks on the buttons(noti, chat, cart and profile) to open them, but it appears that my compiler cant read the …initialState in my code (I’ve tried to map it too)

ERROR MESSAGE ***

object is not iterable (cannot read property Symbol(Symbol.iterator))

TypeError: object is not iterable (cannot read property Symbol(Symbol.iterator))


My CONTEXT PROVIDER

const stateContext = createContext();

const initialState = {
   chat: false,
   cart: false,
   userProfile: false,
   notification: false,
};

export const ContextProvider = ({ children }) => {
   const [ActiveMenu, setActiveMenu] = useState(true);
   const [isClicked, setisClicked] = useState(initialState);
   const handleClick = (clicked) => {setisClicked({ ...initialState, [clicked]: true });};  


  return (
     <stateContext.Provider
          value={{
              ActiveMenu,
              setActiveMenu,
              isClicked,
              setisClicked,
              handleClick,
            }}
      >
          {children}
      </stateContext.Provider>
   );
};
export const useStateContext = () => useContext(stateContext);

In NAVBAR my Context provider sends details to My navbar and i use it to set up values for my button


const NavButton = ({ title, customFunc, icon, dotColor, Color }) => (
   <TooltipComponent content={title} position="BottomCenter">
       <button
         type="button"
         className="relative text-xl rounded-full p-3 hover:bg-light-gray"
         style={{ Color }}
         onClick={customFunc}
       >
           <span
             style={{ background: dotColor }}
             className="absolute inline-flex rounded-full h-2 w-2 right-2 top-2"
           >
              {icon}
           </span>
        </button>
  </TooltipComponent>
);

const Navbar = () => {
  const [ActiveMenu, setActiveMenu, isClicked, setisClicked, handleClick] =
    useStateContext();

  return (
    <div className="flex justify-between p-2 md:mx-6 relative">
      <NavButton
        title="Menu"
        customFunc={() => setActiveMenu((PrevActiveMenu) => !PrevActiveMenu)}
        icon={<AiOutlineMenu />}
        dotColor="#C1ECE4"
        Color="blue"
      />
      <div className="flex justify-around">
        <NavButton
          title="Notifications"
          customFunc={() => handleClick("notification")}
          Color=""
          dotColor="#C1ECE4"
          icon={<MdOutlineNotifications />}
        />
        <NavButton
          title="Chat"
          customFunc={() => handleClick("chat")}
          Color="blue"
          dotColor="#C1ECE4"
          icon={<BsChatRight />}
        />
        <NavButton
          title="Cart"
          customFunc={() => handleClick("cart")}
          Color="blue"
          dotColor="#C1ECE4"
          icon={<BiCartAlt />}
        />
        <TooltipComponent content="Profile" position="BottomCenter">
          <div
            className="vursor-pointer p-1 gap-2 flex items-center hover:bg-light-gray rounded-lg"
            onClick={() => handleClick("userProfile")}
          >
            <img
              src="{avatar}"
              className="rounded-full w-8 h-8"
              alt="avatar.jpg"
            />
            <p>
              <span>Hi, </span> {""}
              <span>Michael</span>
            </p>
          </div>
        </TooltipComponent>
      </div>
    </div>
  );
};

export default Navbar;

2

Answers


  1. May be you should change some of the lines in your code

    CONTEXT PROVIDER:

      const handleClick = (clicked) => {
    setisClicked({ ...isClicked, ...initialState, [clicked]: true });
    

    };

    and

        const useStateContext = () => useContext(stateContext);
    
    export default useStateContext;
    

    This may be helpful for you.

    Login or Signup to reply.
  2. in the context provider, what you are providing for the context’s consumers is an object:

    {
      ActiveMenu,
      setActiveMenu,
      isClicked,
      setisClicked,
      handleClick,
    }
    

    But in Navbar, you are using array destructuring which is wrong:

    const [ActiveMenu, setActiveMenu, isClicked, setisClicked, handleClick] = useStateContext();
    

    the output of useStateContext() is an object not an array and objects are not iterable by default.
    you should use object destructuring:

    const {ActiveMenu, setActiveMenu, isClicked, setisClicked, handleClick} = useStateContext();
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search