【问题标题】:Draft-JS - Entity component doesn't re-render when data changesDraft-JS - 数据更改时实体组件不会重新呈现
【发布时间】:2020-01-27 11:26:43
【问题描述】:

我想让我的文本编辑器显示通过键盘命令选择并执行了多少次内容块。 我通过将实体应用到具有evaluatedTimes 属性的选定块来做到这一点。 数据已正确更改,但实体组件不会重新渲染,直到我在文本块中插入新字符。

实体的装饰器策略没有被调用,所以我找到的唯一方法是使用新的装饰器实例更新编辑器状态。这样实体组件会被重新渲染,但解决方案有点hacky。

依赖:

"draft-js": "^0.11.3",
"draft-js-plugins-editor": "^3.0.0",
"draftjs-utils": "^0.10.2"

代码:

// plugin.js

import { EditorState } from "draft-js";
import { getSelectionText, getSelectionEntity } from "draftjs-utils";
import { EvaluatedSpan } from "./components";
import { findEvaluatedEntities, createEvaluatedEntity } from "./entities";

export function createCodeEvaluationPlugin({ onEvaluate = () => {} }) {
  return {
    decorators: [
      {
        strategy: findEvaluatedEntities,
        component: EvaluatedSpan
      }
    ],

    keyBindingFn: e => {
      // CMD + ENTER
      if (e.metaKey && e.keyCode === 13) {
        return "evaluate";
      }
    },

    handleKeyCommand: (command, editorState, _, { setEditorState }) => {
      if (command === "evaluate") {
        const selectionState = editorState.getSelection();
        const contentState = editorState.getCurrentContent();

        const entityKey = getSelectionEntity(editorState);

        // If selection contains an entity:
        if (!entityKey) {
          // Create new entity and update editor.
          setEditorState(createEvaluatedEntity(editorState, selectionState));
        } else {
          // Modify entity data.
          const entity = contentState.getEntity(entityKey);
          const nextContentState = contentState.mergeEntityData(entityKey, {
            evaluatedTimes: entity.data.evaluatedTimes + 1
          });

          // Update editor.
          setEditorState(
            EditorState.push(editorState, nextContentState, "change-block-data")
          );
        }

        // Pass text to callback handle
        const selectionText = getSelectionText(editorState);
        onEvaluate(selectionText);

        return "handled";
      }
      return "not-handled";
    }
  };
}

【问题讨论】:

  • 我也遇到了这个。考虑到 Draftjs 不可变数据的性质,我会假设,对内容的任何更改都会触发 on 更改。

标签: draftjs draft-js-plugins


【解决方案1】:

据此 (https://github.com/facebook/draft-js/issues/1702),您还可以更新选择状态,这对您来说可能就足够了。

【讨论】:

    【解决方案2】:

    为我工作:

    function forceRerender(editorState: EditorState): EditorState {
        const selectionState = editorState.getSelection();
        return EditorState.forceSelection(editorState, selectionState);
    }
    

    【讨论】:

      猜你喜欢
      • 2021-01-26
      • 2021-07-10
      • 2020-09-14
      • 1970-01-01
      • 1970-01-01
      • 2020-06-27
      • 1970-01-01
      • 2020-01-10
      • 2016-12-05
      相关资源
      最近更新 更多