Question
I'm working on a web application feature that calculates the heat insulation factor for a specific area. You can check out the live Codesandbox example here (it's the third red area with the radio buttons).
The issue I'm facing is that when a user clicks on a radio button, I can see in the console logs that the state updates correctly. However, the "Factor" box on the right side of the page doesn't consistently update when a user clicks on a radio button. I'd like it to update every time a radio button is clicked. How can I achieve this?
Insulation Factor component:
export const InsulFactor = () => {
// Pull in state from Zustand global store
const {
insul,
wellInsul,
poorlyInsul,
notInsul,
setInsul,
setWellInsul,
setPoorlyInsul,
setNotInsul,
} = useInsulFactorStore();
const handleInsulChange = () => {
setInsul(2);
};
const handleWellInsulChange = () => {
setWellInsul(4);
};
const handlePoorlyInsulChange = () => {
setPoorlyInsul(7);
};
const handleNotInsulChange = () => {
setNotInsul(8.5);
};
const getInsulFactor = () => {
if (insul) {
return insul;
}
if (wellInsul) {
return wellInsul;
}
if (poorlyInsul) {
return poorlyInsul;
}
if (notInsul) {
return notInsul;
}
return insul;
};
return (
<>
...
<Row>
<Col lg="4">
<CheckBox
heading="Insulated"
desc="Enclosed area with doors and windows in place."
id="insulated"
name="insulation"
checked={insul === 2}
onChange={handleInsulChange}
/>
</Col>
<Col lg="4">
<CheckBox
heading="Well Insulated"
desc="Sealed environment. Walls constructed but lacking insulation. Doors and windows shielded with plastic sheets or tarps."
id="well-insulated"
name="insulation"
checked={wellInsul === 4}
onChange={handleWellInsulChange}
/>
</Col>
<Col lg="4"> </Col>
</Row>
<Row>
<Col lg="4">
<CheckBox
heading="Poorly Insulated"
desc="Semi-enclosed area with numerous walls in place."
id="poorly-insulated"
name="insulation"
checked={poorlyInsul === 7.5}
onChange={handlePoorlyInsulChange}
/>
</Col>
<Col lg="4">
<CheckBox
heading="Not Insulated"
desc="Uncovered area with primary walls not yet built."
id="not-insulated"
name="insulation"
checked={notInsul === 8}
onChange={handleNotInsulChange}
/>
</Col>
<Col lg="4">
<Result heading="Factor" number={getInsulFactor()} />
</Col>
</Row>
...
</>
);
};
Radio component:
export const CheckBox: React.FC<Props> = ({
heading,
desc,
id,
name,
onChange,
checked,
}) => {
return (
<>
<Form.Group>
<Form.Check
type="radio"
label=""
id={id}
name={name}
onChange={onChange}
defaultChecked={checked}
/>
<h3>{heading}</h3>
<p>{desc}</p>
</Form.Group>
</>
);
};
Reviewing the code I think the issue is in the useInsulFactorStore
You have multiple levels of insul
which then conflict with each other as your getInsulFactor
function will return the first truthy value.
Instead, you should change your context to only have one insul/setInsul
state that then updates depending on the selected option.
I made some edits to the CodeSandBox here with these changes so you can check it out.