Reputation:
I am trying to change a global state to a specific textfield like:
const [values, setValues] = React.useState({ name: '' });
const setName = () => (e: React.ChangeEvent<HTMLInputElement>) => {
setValues({ name: e.target.value });
};
// map starts here
{editMode ? (
<TextField
id={`txt-${category.id}`}
label="New name"
value={values.name}
onChange={setName()}
margin="normal"
/>
)
So when I first click the textfield, it should set the value to both that textfield and global state to category.name
, after typing it should set the textfield value to the global state which is equal to the textfield I'm changing, how can I handle something like this?
Upvotes: 0
Views: 380
Reputation:
Fixed the problem
type InputType = HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement;
const updateField = (id: number, e: React.ChangeEvent<InputType>) => {
setData(prevState => {
return prevState.map(item => {
if (item.id === id) return { ...item, name: e.target.value };
return item;
});
});
};
// inside the map
value={data.find(i => i.id === category.id)!.name}
onChange={e => updateField(category.id, e)}
Upvotes: 1
Reputation: 3745
Remove the second function from setName and remove brackets from TextField's onChange property.
const [values, setValues] = React.useState({ name: '' });
const setName = (e: React.ChangeEvent<HTMLInputElement>) => {
setValues({ name: e.target.value });
};
// map starts here
{editMode ? (
<TextField
id={`txt-${category.id}`}
label="New name"
value={values.name}
onChange={setName}
margin="normal"
/>
)
OR...
You can also write one generic function for setting values instead of setName and the others:
const setAnyValue = (e: React.ChangeEvent<HTMLInputElement>, field: string) => {
setValues({ [field]: e.target.value });
};
And then onChange will look like:
onChange={(e) => setAnyValue(e, 'name')}
Upvotes: 0