Как сделать так, чтобы по потери фокуса input'ом измененный текст попадал в соответствующий li?

function App() {
  const [notes, setNotes] = useState(["1", "2", "3", "4", "5"]);
  const [value, setValue] = useState("");

  function getLiValue(index) {
    setValue(notes[index]);
  }

  /* пытался сделать что-то вроде этого
 но индекс-то undefined, добавляется не то или не так

function getBack(index) {
    setNotes([
      ...notes.slice(0, index),
      (notes[index] = value),
      ...notes.slice(index + 1),
    ]);
  } */

  const result = notes.map((note, index) => {
    return (
      <div>
        <li key={index} onClick={() => getLiValue(index)}>
          {note}
        </li>
      </div>
    );
  });

  return (
    <div>
      <ul>{result}</ul>
      <input
        value={value}
        onChange={(event) => setValue(event.target.value)}
        onBlur={() => getBack()}
      />
    </div>
  );
}

export default App;

Ответы (1 шт):

Автор решения: Armen
// id нужен что бы каждый был уникален
const initialNotes = [
  { id: 1, value: 13123 },
  { id: 2, value: 333 },
  { id: 3, value: "dasdasd" },
];

export const App = () => {
  const [notes, setNotes] = useState(initialNotes);
  const [selectedNote, setSelectedNote] = useState();

  const changeSelectedNoteValue = (value) => {
    //советую использовать setSomething(callback) вариант если в какой то функции нужен доступ к state поскольку
    //есть кейсы в каторых setSomething(new value) привидет к ошибкам
    setSelectedNote((prev) => ({ ...prev, value }));
  };

  const updateNotes = () => {
    //у тебя абстракная связь с notes проподала, правельнее не просто setValue а setSelectedNote ... выбранная note
    //а дальше уже простой перебор
    if(selectedNote) {
      setNotes((prev) => {
        const updatedNotes = prev.map((note) =>
          note.id === selectedNote.id ? selectedNote : note
        );
        return updatedNotes;
      });
    }
  };


  const result = notes.map((note, i) => {
    return (
      //'key' должен быть на верхнем уровне
      //использование 'index' как ключь в некоторых ситуациях может привести к ошибкам(ps: в этом случее норм)
      // правельнее будет юзать note.id(key={note.id})
      <div key={i}>
        <li onClick={() => setSelectedNote(note)}>{note.value}</li>
      </div>
    );
  });

  return (
    <div>
      <ul>{result}</ul>
      <input
        value={selectedNote?.value ?? ""}
        onBlur={updateNotes}
        onChange={(e) => changeSelectedNoteValue(e.target.value)}
      />
    </div>
  );
};
→ Ссылка