如何在 Draft-js 中为块创建、设置样式和定义数据属性?

How to create, style and defined data-attr's to a block in Draft-js?

目前我有这样一个 DraftJS 编辑器:

<Editor
  editorState={this.state.editorState}
  handleKeyCommand={this.handleKeyCommand}
  onChange={this.onChange}
  placeholder="Write a tweet..."
  ref="editor"
  spellCheck={true}
/>

具有状态的构造函数:

constructor(props) {
  super(props);
  const compositeDecorator = new CompositeDecorator([{
    strategy: mentionStrategy,
    component: MentionSpan,
  }, {
    strategy: hashtagStrategy,
    component: HashtagSpan,
  }, {
    strategy: emojiStrategy,
    component: EmojiSpan,
  }]);

  this.state = {
    conversationActive: null,
    editorState: EditorState.createEmpty(compositeDecorator),
  };

  this.focus = () => this.refs.editor.focus();
  this.onChange = (editorState) => this.setState({editorState});
  this.logState = () => console.log(this.state.editorState.toJS());
  this.handleKeyCommand = () => 'not-handled';
}

我甚至制定了一个装饰器策略来匹配一系列正则表达式来确定一个块是否是表情符号,比如 :D:(:| 等.

问题是我无法弄清楚如何 "pass more props" 策略中的元素或如何从匹配中创建实体...

策略如下:

const findWithRegex = (regex, contentBlock, callback) => {
  const text = contentBlock.getText();
  let matchArr, start;
  while ((matchArr = regex.exec(text)) !== null) {
    start = matchArr.index;
    callback(start, start + matchArr[0].length);
  }
}

const emojiRegexes = [...];

export const emojiStrategy = (contentBlock, callback, contentState) => {
  for (let i = 0; i < emojiRegexes.length; i++) {
    findWithRegex(emojiRegexes[i].regex, contentBlock, callback);
  }
}

export const EmojiSpan = (props) => {
  return (
    <span
      className={styles.emoji}
      data-offset-key={props.offsetKey}
    >
      {props.children}
    </span>
  );
};

谁能帮帮我?谢谢!

PS:我似乎无法从 draft-js 中找到真正深入的文档 github 上的文档只有浅薄的描述和虚拟示例。

设法以不同的方式做我想做的事,首先,用 unicode 字符替换文本,这些字符将来将成为具有元数据的实体。代码如下:

onChange(editorState) {
  const contentState = editorState.getCurrentContent();
  let currentText = contentState.getBlockForKey(editorState.getSelection().getAnchorKey()).getText();

  for (let i = 0; i < emojiRegexes.length; i++) {
    currentText = currentText.replace(emojiRegexes[i].regex, () => emojiRegexes[i].unicode)
  }

  if (currentText === contentState.getBlockForKey(editorState.getSelection().getAnchorKey()).getText()) {
    this.setState({ editorState });
    return;
  }

  const updatedSelection = editorState.getSelection().merge({
    anchorOffset: 0,
  });

  const edited = EditorState.push(
    editorState,
    Modifier.replaceText(
      contentState,
      updatedSelection,
      currentText
    ),
    'change-block-data'
  );

  this.setState({ editorState: edited });
}