1

我正在使用 react js 构建 Google Keep 应用程序的克隆。我添加了所有基本功能(扩展创建区域、添加注释、删除它),但我似乎无法管理编辑部分。目前我可以编辑输入并将值存储在状态中,但是如何将初始输入值替换为我在输入中键入的新值?

这是 Note 组件

export default function Note(props) {
  const [editNote, setEditNote] = useState(false);
  const [currentNote, setCurrentNote] = useState({
    id: props.id,
    editTitle: props.title,
    editContent: props.content,
  });

  const handleDelete = () => {
    props.deleteNote(props.id);
  };

  const handleEdit = () => {
    setEditNote(true);
    setCurrentNote((prevValue) => ({ ...prevValue }));
  };

  const handleInputEdit = (event) => {
    const { name, value } = event.target;

    setCurrentNote((prevValue) => ({
      ...prevValue,
      [name]: value,
    }));
  };

  const updateNote = () => {
    setCurrentNote((prevValue, id) => {
      if (currentNote.id === id) {
        props.title = currentNote.editTitle;
        props.content = currentNote.editContent;
      } else {
        return { ...prevValue };
      }
    });
    setEditNote(false);
  };

  return (
    <div>
      {editNote ? (
        <div className='note'>
          <input
            type='text'
            name='edittitle'
            defaultValue={currentNote.editTitle}
            onChange={handleInputEdit}
            className='edit-input'
          />
          <textarea
            name='editcontent'
            defaultValue={currentNote.editContent}
            row='1'
            onChange={handleInputEdit}
            className='edit-input'
          />
          <button onClick={() => setEditNote(false)}>Cancel</button>
          <button onClick={updateNote}>Save</button>
        </div>
      ) : (
        <div className='note' onDoubleClick={handleEdit}>
          <h1>{props.title}</h1>
          <p>{props.content}</p>
          <button onClick={handleDelete}>DELETE</button>
        </div>
      )}
    </div>
  );
}

这是 Container 组件,我在其中渲染 CreateArea 并映射我创建的笔记。我尝试使用新值再次映射笔记,但它不起作用。

export default function Container() {
  const [notes, setNotes] = useState([]);

  const addNote = (newNote) => {
    setNotes((prevNotes) => {
      return [...prevNotes, newNote];
    });
  };

  const deleteNote = (id) => {
    setNotes((prevNotes) => {
      return prevNotes.filter((note, index) => {
        return index !== id;
      });
    });
  };

  // const handleUpdateNote = (id, updatedNote) => {
  //   const updatedItem = notes.map((note, index) => {
  //     return index === id ? updatedNote : note;
  //   });
  //   setNotes(updatedItem);
  // };

  return (
    <div>
      <CreateArea addNote={addNote} />
      {notes.map((note, index) => {
        return (
          <Note
            key={index}
            id={index}
            title={note.title}
            content={note.content}
            deleteNote={deleteNote}
            //handleUpdateNote={handleUpdateNote}
          />
        );
      })}
    </div>
  );
}
4

1 回答 1

0

您的代码中有几个错误。

  1. 状态属性在骆驼情况下
  const [currentNote, setCurrentNote] = useState({
    ...
    editTitle: props.title,
    editContent: props.content,
  });

但是输入的名称是小写的。

          <input
            name='edittitle'
            ...
          />
          <textarea
            name='editcontent'
            ...
          />

因此,在 handleInputEdit 中,您不会更新状态,而是添加新属性:edittitle 和 editcontent。将名称更改为驼峰式。

  1. 在 React 中,你不能分配给组件的 prop 值,它们是只读的。
  const updateNote = () => {
    ...
        props.title = currentNote.editTitle;
        props.content = currentNote.editContent;

您需要改用父组件传递的 handleUpdateNote 函数。您出于某种原因对其进行了评论。

          <Note
            ...
            //handleUpdateNote={handleUpdateNote}
          />

检查下面的代码。我认为它可以满足您的需求。

function Note({ id, title, content, handleUpdateNote, deleteNote }) {
  const [editNote, setEditNote] = React.useState(false);
  const [currentNote, setCurrentNote] = React.useState({
    id,
    editTitle: title,
    editContent: content,
  });

  const handleDelete = () => {
    deleteNote(id);
  };

  const handleEdit = () => {
    setEditNote(true);
    setCurrentNote((prevValue) => ({ ...prevValue }));
  };

  const handleInputEdit = (event) => {
    const { name, value } = event.target;
    setCurrentNote((prevValue) => ({
      ...prevValue,
      [name]: value,
    }));
  };

  const updateNote = () => {
    handleUpdateNote({
      id: currentNote.id,
      title: currentNote.editTitle,
      content: currentNote.editContent
    });
    setEditNote(false);
  };

  return (
    <div>
      {editNote ? (
        <div className='note'>
          <input
            type='text'
            name='editTitle'
            defaultValue={currentNote.editTitle}
            onChange={handleInputEdit}
            className='edit-input'
          />
          <textarea
            name='editContent'
            defaultValue={currentNote.editContent}
            row='1'
            onChange={handleInputEdit}
            className='edit-input'
          />
          <button onClick={() => setEditNote(false)}>Cancel</button>
          <button onClick={updateNote}>Save</button>
        </div>
      ) : (
        <div className='note' onDoubleClick={handleEdit}>
          <h1>{title}</h1>
          <p>{content}</p>
          <button onClick={handleDelete}>DELETE</button>
        </div>
      )}
    </div>
  );
}

function CreateArea() {
  return null;
}

function Container() {
  const [notes, setNotes] = React.useState([
    { title: 'Words', content: 'hello, bye' },
    { title: 'Food', content: 'milk, cheese' }
  ]);

  const addNote = (newNote) => {
    setNotes((prevNotes) => {
      return [...prevNotes, newNote];
    });
  };

  const deleteNote = (id) => {
    setNotes((prevNotes) => {
      return prevNotes.filter((note, index) => {
        return index !== id;
      });
    });
  };

  const handleUpdateNote = ({ id, title, content }) => {
    const _notes = [];
    for (let i = 0; i < notes.length; i++) {
      if (i === id) {
        _notes.push({ id, title, content });
      } else {
        _notes.push(notes[i]);
      }
    }
    
    setNotes(_notes);
  };

  return (
    <div>
      <CreateArea addNote={addNote} />
      {notes.map((note, index) => {
        return (
          <Note
            key={index}
            id={index}
            title={note.title}
            content={note.content}
            deleteNote={deleteNote}
            handleUpdateNote={handleUpdateNote}
          />
        );
      })}
    </div>
  );
}


function App() {
  return (
    <div>
      <Container />
    </div>
  );
}

ReactDOM.render(
  <App />,
  document.getElementById('root')
);
<script src="https://unpkg.com/react@17/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js" crossorigin></script>
<div id="root"></div>

此外,您可以将注释存储在对象或哈希映射中而不是数组中。例如

     const [notes, setNotes] = React.useState({
        'unique_id': { title: 'Words', content: 'hello, bye' }
      });

然后在 handleUpdateNote 你有

setNotes((prev) => ({ ...prev, unique_id: { title, content } }))

于 2021-10-21T14:28:49.967 回答