I am a React beginner but I did a very basic form component that does not work! It is this. What is the trouble? Maybe the value={prop.value}
?
ReactDOM
.createRoot(document.getElementById('root'))
.render(<App />);
function App() {
const data = [
{
type: 'text',
name: 'name',
label: 'Name',
value: 'Alfred'
},
{
type: 'number',
name: 'amount',
label: 'Amount',
value: 23
},
{
type: 'date',
name: 'birthday',
label: 'Date',
value: '1987-02-01'
}
];
return <Form data={data} />;
}
function Form(props) {
let [data, setData] = React.useState(props.data);
const handleChange = (e) => {
let elem = e.target;
setData((data) => {
const prop = data[elem.dataset.index];
console.log('Input \'' prop.name '\' becomes from \'' prop.value '\' to \'' elem.value '\'');
data[elem.dataset.index].value = elem.value;
return data;
});
};
return (
<form>
{data.map((prop, i) => {
const id = "input-" prop.name;
return (
<div key={prop.name}>
<label htmlFor={id}>{prop.label}</label>
<span>: </span>
<input
type={prop.type}
id={id}
value={prop.value}
onChange={handleChange}
data-index={i}
/>
</div>
);
})}
</form>
);
}
<script crossorigin src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
<div id="root"></div>
CodePudding user response:
React's state is immutable, so you cannot modify the array data directly.
You have to change return data
to return [...data]
which is to clone your array to a new value in setData
of handleChange
ReactDOM
.createRoot(document.getElementById('root'))
.render(<App />);
function App() {
const data = [
{
type: 'text',
name: 'name',
label: 'Name',
value: 'Alfred'
},
{
type: 'number',
name: 'amount',
label: 'Amount',
value: 23
},
{
type: 'date',
name: 'birthday',
label: 'Date',
value: '1987-02-01'
}
];
return <Form data={data} />;
}
function Form(props) {
let [data, setData] = React.useState(props.data);
const handleChange = (e) => {
let elem = e.target;
setData((data) => {
const prop = data[elem.dataset.index];
console.log('Input \'' prop.name '\' becomes from \'' prop.value '\' to \'' elem.value '\'');
data[elem.dataset.index].value = elem.value;
return [...data]; //the change is here
});
};
return (
<form>
{data.map((prop, i) => {
const id = "input-" prop.name;
return (
<div key={prop.name}>
<label htmlFor={id}>{prop.label}</label>
<span>: </span>
<input
type={prop.type}
id={id}
value={prop.value}
onChange={handleChange}
data-index={i}
/>
</div>
);
})}
</form>
);
}
<script crossorigin src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
<div id="root"></div>