I’m passing a value from one input tag to another input tag, which are in different independent sections. And after passing the value, I can’t edit the input to which I passed the value. Here is the error:
You provided a value prop to a form field without an onChange handler. This will render a read-only field. If the field should be mutable use defaultValue. Otherwise, set either onChange or readOnly.
I get the values, but I can’t edit the inputs!
Here is code:
App.js
import React from 'react';
import { useState } from 'react';
import { StartingSection } from './components/StartingSection';
import { CustomizerSection } from './components/CustomizerSection';
function App() {
const [checkSection, setSection] = useState(false);
const showCustomizerSection = () => setSection(true);
const [Width, setWidth] = useState();
const [Length, setLength] = useState();
return (
<div className="App">
{checkSection ?
<CustomizerSection
Width={Width}
Length={Length}
/>
:
<StartingSection
Width={Width}
setWidth={setWidth}
Length={Length}
setLength={setLength}
onClick={showCustomizerSection}
/>
}
</div>
);
StartingSection.jsx
export function StartingSection({onClick, Width, setWidth, Length, setLength}) {
return(
<div>
<input type="number" value={Width || ''} onChange={event => setWidth(event.target.value)} />
<input type="number" value={Length || ''} onChange={event => setLength(event.target.value)} />
<button className="button w-100" onClick={onClick}>Continue</button>
</div>
)
}
CustomizerSection.jsx
I pass values to this section, and at this point the error that I indicated above occurs.
export function CustomizerSection({Width, Length}) {
return(
<div>
<input type="number" value={Width} /> <=== this is where I pass the value
<input type="number" value={Length} /> <=== this is where I pass the value
</div>
)
}
What could be the problem? Thanks!
>Solution :
To me, it looks like the error message is correctly identifying the situation. You are binding a value for Width for example, but you are not allowing anything to change Width once it is set.
I don’t see where you are using setSection, but it looks as if once StartingSection is used, then CustomizerSection is displayed. However, once CustomizerSection is displayed it cannot make use of setWidth or setLength in order to change the values. This causes the situation where you get a read only textbox (due to one-way binding of the values).
If you would like to use the StartingSection as initial values and then change them, you need to manage separate state for the new CustomizerSection values:
function App() {
const [checkSection, setSection] = useState(false);
const showCustomizerSection = () => setSection(true);
const [Width, setWidth] = useState();
const [Length, setLength] = useState();
const [customizedWidth, setCustomizedWidth] = useState(Width);
const [customizedLength, setCustomizedLength] = useState(Length);
return (
<div className="App">
{checkSection ?
<CustomizerSection
Width={customizedWidth}
setWidth={setCustomizedWidth}
Length={customizedLength}
setLength={setCustomizedLength}
/>
:
<StartingSection
Width={Width}
setWidth={setWidth}
Length={Length}
setLength={setLength}
onClick={showCustomizerSection}
/>
}
</div>
);
Changes to CustomizerSection:
export function CustomizerSection({Width, Length, setWidth, setLength}) {
return(
<div>
<input type="number" value={Width} onChange={event => setWidth(event.target.value)} />
<input type="number" value={Length} onChange={event => setHeight(event.target.value)} />
</div>
)
}