I am using useContext to reference and update useState variables across multiple components without the need to drop props several component layers deep. The problem I am running across is that when I update the useState variable it appears that it isn’t read as updated to the new value until the function is called again.
Here’s the Context code:
import React, { useContext, useState } from 'react';
const AttributeContext = React.createContext({
strength: "10",
dexterity: "10",
constitution: "10",
intelligence: "10",
wisdom: "10",
charisma: "10"
})
export function useAttributeContext() {
return (useContext(AttributeContext))
}
export function AttributeContextProvider({children}) {
const [strength, setStrength] = useState("10")
const [dexterity, setDexterity] = useState("10")
const [constitution, setConstitution] = useState("10")
const [intelligence, setIntelligence] = useState("10")
const [wisdom, setWisdom] = useState("10")
const [charisma, setCharisma] = useState("10")
const updateStr = (value) => {
if (value === "") {
console.log("nothing changed. Selection empty")
} else {
console.log(value)
setStrength(value)
}
console.log(strength)
}
const updateDex = (value) => {
if (value === "") {
console.log("nothing changed. Selection empty")
} else {
console.log(value)
setDexterity(value)
}
console.log(dexterity)
}
const updateCon = (value) => {
if (value === "") {
console.log("nothing changed. Selection empty")
} else {
console.log(value)
setConstitution(value)
}
console.log(constitution)
}
const updateInt = (value) => {
if (value === "") {
console.log("nothing changed. Selection empty")
} else {
console.log(value)
setIntelligence(value)
}
console.log(intelligence)
}
const updateWis = (value) => {
if (value === "") {
console.log("nothing changed. Selection empty")
} else {
console.log(value)
setWisdom(value)
}
console.log(wisdom)
}
const updateCha = (value) => {
if (value === "") {
console.log("nothing changed. Selection empty")
} else {
console.log(value)
setCharisma(value)
}
console.log(charisma)
}
const value = {
strength,
updateStr,
dexterity,
updateDex,
constitution,
updateCon,
intelligence,
updateInt,
wisdom,
updateWis,
charisma,
updateCha
}
return (
<AttributeContext.Provider value={value}>
{children}
</AttributeContext.Provider>
)
}
and where it is called:
const handleChange = (ev) => {
setChosenOptions({...chosenOptions, [ev.target.name]: ev.target.value});
let value = ""
if (ev.target.value === "14-1") {
value = "14"
} else if (ev.target.value === "12-1") {
value = "12"
} else {value = ev.target.value}
switch (ev.target.name) {
case "Strength":
updateStr(value)
break;
case "Dexterity":
updateDex(value)
break;
case "Constitution":
updateCon(value)
break;
case "Intelligence":
updateInt(value)
break;
case "Wisdom":
updateWis(value)
break;
case "Charisma":
updateCha(value)
break;
default:
console.log("Select tag not recognized")
break;
}
};
It calls the functions just fine but the console.log shows the value I want to change it to as expected but that second one showing me the value of the useState I wanted to change shows it as the previous value before change. When called a second that second log shows the value I wanted to change it to previously. I want to make sure that It is updating when I call it the first time. I’m unsure why it’s happening this way as I’m pretty sure my console.log statements are in the correct order to report it how I’m expecting.
logs look as follows:
16 this is the console.log(value)
10 this is the console.log(strength)
second time called it appears as such:
14 this is the console.log(value) with a different choice
16 this is the console.log(strength)
How would I fix this?