2

check this code please https://stackblitz.com/edit/react-koqfzp?file=src/Section.js

Everytime i add an item, i'm also adding an random number that i want to edit. The number is rendered at a MUI Text field component.

<TextField
            type="number"
            variant="standard"
            aria-readonly={edit === true ? false : true}
            value={edit === true ? value : numbers[i]}
            onChange={(e) => setValue(e.target.value)}
          />

And the buttons are rendered based on edit's state, like this:

{edit === true ? (
            <button onClick={() => saveEdit(i)}>Save</button>
          ) : (
            <button onClick={() => setEdit(true)}>Edit</button>
          )}

And it's working, i can edit it and rerender with the new value, the problem is that when i click the edit button, every field receives the new input value and the save button shows up in every field, though when i save it, it returns to it's original value. How i can do what i'm doing but to just one specific field?

José Carlos
  • 626
  • 3
  • 23

3 Answers3

2

The problem is that you are using setEdit as a boolean

You can define it as the index of the array to edit with -1 as starting value

const [edit, setEdit] = useState(-1)
...

{edit === i ? (
            <button onClick={() => saveEdit(i)}>Save</button>
          ) : (
            <button onClick={() => setEdit(i)}>Edit</button>
          )}

R4ncid
  • 6,944
  • 1
  • 4
  • 18
2

I recommend creating another component Exemple:Item with it has it's own states edit,value states And pass the needed props to it which are the value,numbers,saveEdit(index,newValue),removeItem(index) and also the index

saveEdit has to be changed in section by passing the index and the newValue

I hope this clear for you

ZomitaKa
  • 475
  • 2
  • 7
1

add the map values in a component and add the states inside the component so you will have multiple states for each component not just 1

parent component

{section.items.map((item, i) => (
     <Component key={i} item={item}/>
)}

child component

const Component = ({ section, addItem, removeItem}) => {
   const [newItem, setNewItem] = useState('');
   const [edit, setEdit] = useState(false);
   const [value, setValue] = useState(0);
   const [numbers, setNumbers] = useState(section.number);

   const handleChange = (e) => {
        setNewItem(e.target.value);
   };

   return (
      <TextField
        type="number"
        variant="standard"
        aria-readonly={edit === true ? false : true}
        value={edit === true ? value : numbers[i]}
        onChange={(e) => setValue(e.target.value)}
      />
   )
codmitu
  • 636
  • 7
  • 9
  • So each item of section.items would be a component alone? – José Carlos Apr 22 '22 at 19:14
  • yes so they will have their own states to keep the values so they will not fight for the states, which item keeps it's value in which state... if you know what i mean :)) like the variable const can hold 1 value, useState also holds 1 value but by adding it in a looped component you can use eg: const array = 0 as many times if they are in separate components – codmitu Apr 22 '22 at 19:23