I have a React component representing a form with inputs (Text, Number, Date). The date input has a default value - today. I use this component for two functions: creating an object and editing an object. In the first case, all inputs are empty by default, except for the date input, which is set to today. In the second case, the inputs receive default values from optional props (values) that are passed to the component from the parent component's state. The component is rendered on the page in two instances, one with values passed and one without. Since the presence of values is optional, I included a conditional operator in the default values of each input. In the case of the date input, it looks like this:
defaultValue={inputValues?.date ? inputValues.date : today}
In other cases, an empty string '' is used instead of today.
I expected that when the state changes, the component would re-render and insert the values into the default inputs. In practice, this only happens with inputs that are initially empty, while the date input always has the value today.
Through the console, I see that when the component is rendered, inputValue = undefined (useState is set with empty brackets, so it's not a surprise), so initially I assumed that the values do not appear by the time of rendering. However, when the edit button is clicked, the correct values are displayed in the console. In my understanding, at this point, the component should re-render and insert the values according to the expression {inputValues?.date ? inputValues.date : today}. However, in fact, the value of the date picker is today, and the value of all other inputs is values. If you replace today with an '' in the expression, then when the edit function is called, the value of the date picker in the edit form is inputValues.date, but the default value in the creation form is now empty, because today is not set in this case.
This behavior is not exclusive to the date picker; any other input behaves in the same way if you replace '' with any value in the expression. I would be very glad if you could explain this behavior and how to fix it.
Here is a test example:"
function App() {
const [values, setValues] = React.useState();
const change = () => setValues({ name: 'name', date: '2023-11-28' });
return (
<Child values={values} change={change} />
);
}
function Child({ values, change }) {
console.log(values);
return (
<div className="container">
<button type="button" onClick={change} >clickMe</button>
<input type="text" defaultValue={values?.name ? values.name : ''} />
<input type="date" defaultValue={values?.date ? values.date : '2023-11-20'} />
</div>
);
}
const domContainer = document.querySelector('#like_button_container');
const root = ReactDOM.createRoot(domContainer);
root.render(<App />);
The issue you're facing is related to the fact that the defaultValue attribute is only set once when the component initially renders. Changing the values prop doesn't trigger a re-render of the child component, so the defaultValue remains unchanged.