i have a navbar and list of tags like
computer , phone , pc , camera
i filter products by tags and it work on console and change in my context but doesnt re render
i feel like i do mutating it somewhere but i didnt find any of it can someone help me
i already provide the context to app
i read a couple of same problem but didnt find the answer
//side context
"use client";
import React, { useEffect } from "react";
import { createContext, useState } from "react";
export const sideContext = createContext();
export default function SidebarContext({ children }) {
const [side, setSide] = useState({ buka: false, data: [] });
return (
<sideContext.Provider value={{ side, setSide }}>
{children}
</sideContext.Provider>
);
}
//navbar compponent
export default function Navbar() {
const navv = ["Camera", "Laptop", "TV", "Cosole", "Phone"];
const { side, setSide } = useContext(sideContext);
console.log(side);
const handle = (tags) => {
let cari = product.filter((item) => {
if (tags === item.tags) {
return item;
}
});
setSide((prev) => {
return { ...prev, data: [cari] };
});
}; // i think this code is the problem of mutating
return (
<>
<div>
<div className="grid h-10 md:h-40">
<div className="flex justify-center mt-0">
<div className=" self-center">
<h1 className="text-start font-semibold font-serif">
Tech Trend
</h1>
</div>
<div className="flex gap-10 p-20 ">
<div className="flex">
<ShoppingCartIcon />
<p className=" text-red-600 border border-black rounded-full w-5 h-5 text-center self-center">
5
</p>
</div>
<button
onClick={() => {
setSide((prev) => {
return { ...prev, buka: !prev.buka };
});
}}
>
<MenuOpenIcon />
</button>
</div>
</div>
<div className="flex gap-10 justify-evenly border border-black md:visible">
<div className="flex gap-10">
{navv.map((item) => {
return (
<button
className="text-black"
key={crypto.randomUUID()}
onClick={() => {
return handle(item);
}}
>
{item}
</button>
);
})}
</div>
</div>
</div>
</div>
</>
);
}
//page.js
const boogie = product.map((item) => {
return item;
});
console.log("boogie ", boogie);
export default function Home() {
const { side, setSide } = useContext(sideContext);
useEffect(() => {
setSide((prev) => {
return { ...prev, data: boogie };
});
}, []);
return (
<>
<SideBar>
<Navbar />
<SwipeNavbar />
<Wrapbox>
{side.data &&
side.data.map((item) => {
return <BoxList key={item.id} data={item} />;
})}
</Wrapbox>
</SideBar>
</>
);
}
2
Answers
I found the answer it need spread operator to the new element so its looks like this
It appears that you have identified the issue correctly.
To fix this issue, you should directly set cari as the new value for the data field in the side state, rather than wrapping it in an array. Here’s the updated handle function:
With this change, data will directly contain the filtered products as an array, which should correctly trigger a re-render when the data changes.
Additionally, make sure that the product array is updated when necessary, as it seems to be the source of the data you’re filtering in the handle function. If product is not updated correctly, it may not reflect the changes you expect.