You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React项目中如何将contentEditable内容保存至state数组?

问题分析与解决方案

你现在的核心问题是把拖拽组件的onChange和内容编辑的事件搞混了:Draggable组件的onChange是监听拖拽位置变化的,和contentEditable元素的编辑行为完全无关,所以你编辑文本时根本不会触发这个回调。另外你的Note组件还漏接收了id属性,父组件传了但没解构。

修复步骤:

  1. 给可编辑元素绑定正确的输入事件
    对contentEditable="true"的<p>标签,应该监听onInput(实时响应输入)或者onBlur(失去焦点时保存)事件,获取当前编辑的内容后传给父组件。

  2. 正确更新父组件的notes数组
    父组件的handleOnChange需要根据id找到对应note,更新它的content,这里要用函数式更新setNotes(prev => ...),确保拿到最新的状态。

修改后的完整代码:

// 修正Note组件:接收id,给可编辑p绑定输入事件
function Note({ id, content, onWrite }) {
  const handleContentChange = (e) => {
    // 获取当前编辑的内容,用textContent避免HTML标签,或者innerHTML保留格式
    const newContent = e.target.textContent;
    onWrite(id, newContent);
  };

  return (
    <Draggable bounds="parent" axis="both">
      <div className="note">
        <p contentEditable="true" onInput={handleContentChange}>
          {content}
        </p>
      </div>
    </Draggable>
  );
}

function App() {
  const [notes, setNotes] = useState([]);

  // 修正handleOnChange:根据id更新对应note的内容
  function handleOnChange(noteId, newContent) {
    console.log('A note was changed');
    setNotes(prevNotes => 
      prevNotes.map(note => 
        note.id === noteId ? { ...note, content: newContent } : note
      )
    );
  }

  return (
    <div className="App">
      <h1>THIS IS A TEST</h1>
      <button onClick={() => {
        const newNote = { id: uuid(), content: 'Type something' };
        setNotes(prev => [...prev, newNote]);
        // 注意:setState是异步的,直接log notes拿不到最新值,要log newNote或者用useEffect监听变化
        console.log(newNote);
      }}>+</button>
      <div className="notes">
        {notes.map(note => (
          <Note 
            key={note.id} 
            id={note.id}  {/* 补上id属性传递 */}
            content={note.content} 
            onWrite={handleOnChange}
          />
        ))}
      </div>
    </div>
  );
}

额外提示:

  • 如果不想实时更新,把onInput换成onBlur,只会在用户离开便签时保存内容,减少状态更新次数
  • contentEditable会生成HTML标签,如果不需要格式,用textContent获取内容;需要保留格式的话用innerHTML
  • 原代码中点击按钮后console.log(notes)拿不到最新值,因为setNotes是异步的,要么log新创建的newNote,要么用useEffect监听notes变化再打印

内容的提问来源于stack exchange,提问作者Metaphysical Madman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 14:56:25