How to re-render all child components
Unanswered
Munchkin posted this in #help-forum
MunchkinOP
With the way i have currently written my code. I have a lot of child components that all get a predefined variable which changes when the player loads in their userdata.
Now the problem is, is that unless i add a useeffect hook to every child component. the page wont get updated.
Therefore I would like to have a way to forcefully reload my whole page once i get my variable updated.
Not providing code yet but willing to do so at request.
Now the problem is, is that unless i add a useeffect hook to every child component. the page wont get updated.
Therefore I would like to have a way to forcefully reload my whole page once i get my variable updated.
Not providing code yet but willing to do so at request.
28 Replies
MunchkinOP
Have you tried router.refresh() client side or revalidatePath server-side?
MunchkinOP
That doesnt seem to work as i think it throws away the variable it just got from local storage
//SaveSystem.jsx
"use client";
import { CharacterInfo } from "./Variables";
function SaveFile() {
localStorage.setItem("Storage", JSON.stringify(CharacterInfo));
}
function LoadFile() {
const doc = JSON.parse(localStorage.getItem("Storage"));
if (doc) {
Object.assign(CharacterInfo, doc);
}
console.log("Loaded documents: " + JSON.stringify(CharacterInfo))
document.dispatchEvent(new Event("CharacterFileUpdated"))
}
export { SaveFile, LoadFile};//StatContainer
//Reload Current page
const [forceUpdate, setForceUpdate] = useState(false);
const HandleEvent = () => {
// setForceUpdate((prev) => !prev);
router.refresh();
};
useEffect(() => {
document.addEventListener("CharacterFileUpdated", HandleEvent);
return () => {
document.removeEventListener("CharacterFileUpdated", HandleEvent);
};
}, []);
return (
<div className="statsContainer">
<StatBox
key={`Strength-${forceUpdate}`}
forceUpdate={forceUpdate}
statName={"Strength"}
defaultValue={CharacterInfo.playerStats.Strength}
Skills={["Saving throw", "Athletics"]}
onValueChanged={(value) => HandleValueChange(value, "Strength")}
/>
<StatBox
key={`Constitution-${forceUpdate}`}
forceUpdate={forceUpdate}
statName={"Constitution"}
defaultValue={CharacterInfo.playerStats.Constitution}
Skills={["Saving throw"]}
onValueChanged={(value) => HandleValueChange(value, "Constitution")}
/>
<StatBox
key={`Dexterity-${forceUpdate}`}
forceUpdate={forceUpdate}
statName={"Dexterity"}
defaultValue={CharacterInfo.playerStats.Dexterity}
Skills={["Saving throw", "Acrobatics", "Sleight of hand", "Stealth"]}
onValueChanged={(value) => HandleValueChange(value, "Dexterity")}
/>
<StatBox
key={`Intelligence-${forceUpdate}`}
forceUpdate={forceUpdate}
statName={"Intelligence"}
defaultValue={CharacterInfo.playerStats.Intelligence}
Skills={[
"Saving throw",
"Arcana",
"History",
"Investigation",
"Nature",
"Religion",
]}
onValueChanged={(value) => HandleValueChange(value, "Intelligence")}
/>
}MunchkinOP
Loadfile creates and event and emits it. Then on my other component. I listen for it and then refresh the router
oh and loadfile is being called by a button
let me grab that
//BottomContainer.jsx
<div className="BottomInfoContainerButtons">
<button onClick={() => ActiveInfoPage("SpellsContainer")}>
Spells
</button>
<button onClick={() => ActiveInfoPage("InventoryContainer")}>
Inventory
</button>
<button onClick={() => ActiveInfoPage("Info")}>Character info</button>
<button onClick={()=>SaveFile()}>Save Document</button>
<button onClick={()=>LoadFile()}>Load Document</button>
</div>do
StatContainer and BottomContainer render on the same page?MunchkinOP
Yes they do. they both get called as childcomponents on my page.jsx
import TopbarInfo from '@/components/TopbarInfo'
import UnderInfo from '@/components/UnderProfile'
import StatsContainer from '@/components/StatsContainer'
import BottomContainer from '@/components/BottomContainer'
export const metadata = {
title: 'D&DMCT | Sheet',
description: 'D&D Character Management Tool'
}
export default function Home() {
return (
<main >
<div className="topContainer">
<TopbarInfo />
<UnderInfo />
<StatsContainer />
</div>
<BottomContainer />
</main>
)
}MunchkinOP
Yeah the event is being called and i see the page refresh. Its just that my child components dont get the updated value.
which in this case is CharacterInfo.playerStats.*
@Munchkin which in this case is CharacterInfo.playerStats.*
https://docs.pmnd.rs/zustand/integrations/persisting-store-data
I think its better to use zustand for this
I think its better to use zustand for this
MunchkinOP
alright. i mean I am intending for it to be stored at my appwrite DB in a later point but i just wanted to get the values brought over before i put stuff in a db.
you create the store in zustand and persist it in localstorage. and the component subscribe to the store for the data
MunchkinOP
Sounds like there should be an easier way of doing this but understandable.
Ill try to tinker a bit more as i need to redo my login page as well to hold cookie data etc.
Thank you for your answer for now and if i have more question ill make a new ticket.
Ill try to tinker a bit more as i need to redo my login page as well to hold cookie data etc.
Thank you for your answer for now and if i have more question ill make a new ticket.
@Munchkin Sounds like there should be an easier way of doing this but understandable.
Ill try to tinker a bit more as i need to redo my login page as well to hold cookie data etc.
Thank you for your answer for now and if i have more question ill make a new ticket.
or if you don't mind a full page reload, you could try this
const HandleEvent = () => {
// setForceUpdate((prev) => !prev);
window.location.reload()
};MunchkinOP
I dont mind doing that but that removes the localstorage 🙂
@Munchkin I dont mind doing that but that removes the localstorage 🙂
it remove the data in localstorage?
MunchkinOP
i mean i will have to call loadfile again to apply the data.
oh yeah lol
MunchkinOP
which puts me in a loop :p
I think i should just tinker with my site for now and immediately put it the way i want.
that way i wont have to deal with this