user10471818
user10471818

Reputation:

Change specific textfield inside map

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

Answers (2)

user10471818
user10471818

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

zilijonas
zilijonas

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

Related Questions