【问题标题】:edit notes on a Google Keep clone app with React js使用 React js 在 Google Keep 克隆应用上编辑笔记
【发布时间】:2021-10-21 11:41:17
【问题描述】:

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

这是笔记组件

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>
  );
}

【问题讨论】:

    标签: javascript reactjs google-keep


    【解决方案1】:

    您的代码中有几个错误。

    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 } }))
    
    

    【讨论】:

    • 非常感谢!!有效。另外,我正在阅读有关受控和不受控组件的信息,因为在应用您的更改之前, value 属性不允许我在输入上键入任何内容。我应用了您的建议,将 defaultValue 更改为 value,一切看起来都很完美。再次感谢!
    • 实际上我再次尝试创建不同的笔记,但是当我编辑其中一个时,修改被保存,但其他笔记的内容变为未定义
    • @OrianaAbreu 我修正了代码中的一个错字:_notes.push(note) -> _notes.push(notes[i])
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-02
    • 1970-01-01
    • 2021-08-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多