I have a situation where I want to set the default value of a radio group as a side effect of a deferred call. However, it would appear that the defaultValue property is ignored on a state update, and I’m at a loss to understand why. Here is a simple example, which I ran through https://playcode.io/react:
import React from 'react';
export function App(props) {
const [defaultValue, setDefaultValue] = React.useState(1);
React.useEffect(() => {
setDefaultValue(2);
});
console.log(defaultValue);
return (
<div className='App'>
<input type="radio" name="whatever" value="0" defaultChecked={defaultValue === 0}></input>Value 0
<input type="radio" name="whatever" value="1" defaultChecked={defaultValue === 1}></input>Value 1
<input type="radio" name="whatever" value="2" defaultChecked={defaultValue === 2}></input>Value 2
</div>
);
}
As you can see, the initial state of the default value is 1, which is then changed to 2 once useEffect() takes place.
I did manage to work around this by setting the "checked" property instead and putting in an onChange handler to store the value, but I’m really curious as to why defaultChecked isn’t working when the state changes.
2
Answers
If you want the defaultValue state to determine the selected radio button and react to state updates, you need to use the checked property instead of defaultChecked. Here’s how you can adjust your code:
This is because the
defaultChecked
property in React only works when the component is initially rendered and is ignored on subsequent renders or state updates.The
defaultChecked
attribute is used to set the initial checked state of an input element. This is a static initialization property—it only affects the DOM element on its first render. React doesn’t update thedefaultChecked
attribute when the component is re-rendered after a state or prop change. Instead, React expects you to control the checked state explicitly via thechecked
property if you want to dynamically change the value.The reason why
defaultChecked
isn’t working when the state changes as per your example.Initially,
defaultValue
is1
, so the second radio input’sdefaultChecked
evaluates totrue
during the initial render.On the next render (after the
useEffect
setsdefaultValue
to 2), thedefaultChecked
attribute doesn’t update because React doesn’t reapplydefaultChecked
on updates. The radio buttons maintain their existing state unless explicitly controlled.