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

React父组件状态变更后如何更新子组件Props?Draft.js状态传递问题

这个场景我太熟悉了!之前在做Draft.js相关的项目时也碰到过类似的状态同步问题,完全不用依赖setTimeout这种hack或者已经被官方废弃的UNSAFE生命周期,React本身就有几个优雅的解决方案,我给你梳理一下:

方案1:同步初始状态,避免无效props传递

Draft.js的CustomEditor内部默认会用EditorState.createEmpty()初始化编辑器状态,那你可以在顶层的Notes组件里,也用同样的初始值来初始化state。这样一来,Sidebar从一开始拿到的就是和编辑器一致的有效状态,后续编辑器状态变化时,通过回调更新Notes的state,Sidebar也会实时同步最新值。

举个函数组件的例子:

import { useState } from 'react';
import { EditorState } from 'draft-js';

function Notes() {
  // 初始化和Draft.js编辑器一致的空状态
  const [editorState, setEditorState] = useState(EditorState.createEmpty());

  // 接收编辑器状态变化的回调
  const handleEditorChange = (newState) => {
    setEditorState(newState);
  };

  return (
    <div className="notes-container">
      {/* 把初始状态传给CustomEditor,确保两边起始状态一致 */}
      <CustomEditor 
        initialEditorState={editorState}
        onStateChange={handleEditorChange} 
      />
      {/* 直接传递同步后的state给Sidebar */}
      <Sidebar currentEditorState={editorState} />
    </div>
  );
}

如果是类组件,逻辑也是一样的,在constructor里初始化state即可:

import { Component } from 'react';
import { EditorState } from 'draft-js';

class Notes extends Component {
  constructor(props) {
    super(props);
    this.state = {
      editorState: EditorState.createEmpty()
    };
  }

  handleEditorChange = (newState) => {
    this.setState({ editorState: newState });
  };

  render() {
    return (
      <div className="notes-container">
        <CustomEditor 
          initialEditorState={this.state.editorState}
          onStateChange={this.handleEditorChange} 
        />
        <Sidebar currentEditorState={this.state.editorState} />
      </div>
    );
  }
}
方案2:条件渲染,确保Sidebar只接收就绪状态

如果你的编辑器初始化逻辑比较特殊(比如从后端加载内容),没法提前同步初始状态,那可以给Sidebar加个渲染条件,只有当editorState真正就绪时才渲染它,或者给它传一个兜底的空状态,避免接收无效值:

function Notes() {
  const [editorState, setEditorState] = useState(null);

  const handleEditorChange = (newState) => {
    setEditorState(newState);
  };

  return (
    <div className="notes-container">
      <CustomEditor onStateChange={handleEditorChange} />
      {/* 只有当editorState存在时才渲染Sidebar */}
      {editorState && <Sidebar currentEditorState={editorState} />}
      {/* 或者给Sidebar传兜底的空状态 */}
      {/* <Sidebar currentEditorState={editorState || EditorState.createEmpty()} /> */}
    </div>
  );
}
方案3:用Context API简化状态共享(推荐复杂场景)

如果你的组件层级比较深,或者有多个组件需要用到这个编辑器状态,那用React的Context API来管理状态会更省心,不用一层层传递props,也能完美解决同步问题:

首先创建一个编辑器状态的Context:

import { createContext, useContext, useState } from 'react';
import { EditorState } from 'draft-js';

// 创建Context
const EditorContext = createContext();

// 封装Provider组件
export function EditorProvider({ children }) {
  const [editorState, setEditorState] = useState(EditorState.createEmpty());

  return (
    <EditorContext.Provider value={{ editorState, setEditorState }}>
      {children}
    </EditorContext.Provider>
  );
}

// 封装自定义Hook,方便组件使用
export function useEditor() {
  return useContext(EditorContext);
}

然后在Notes组件里用Provider包裹子组件:

function Notes() {
  return (
    <EditorProvider>
      <CustomEditor />
      <Sidebar />
    </EditorProvider>
  );
}

之后CustomEditor和Sidebar就可以直接通过自定义Hook获取状态和更新方法,不用再传递props:

// CustomEditor组件
import { useEditor } from './EditorContext';

function CustomEditor() {
  const { editorState, setEditorState } = useEditor();
  
  return (
    <Editor
      editorState={editorState}
      onChange={setEditorState}
    />
  );
}

// Sidebar组件
import { useEditor } from './EditorContext';

function Sidebar() {
  const { editorState } = useEditor();
  
  return (
    <div className="sidebar">
      {/* 直接使用editorState进行渲染 */}
      <p>当前内容长度:{editorState.getCurrentContent().getPlainText().length}</p>
    </div>
  );
}

这种方式不仅解决了状态同步的问题,还让代码结构更清晰,后期维护也更方便。

总的来说,优先选择方案1(同步初始状态)或者方案3(Context API),都是React官方推荐的做法,完全不用依赖那些不优雅的临时解决方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:16:45