2

嗨,我在 Draft-JS 中遇到问题。我想更改文本,例如当用户键入“:)”时它会更改为表情符号,但在此示例中,我只想更改一些使用“**”的单词进行测试。不知何故,handleInput 中的 this.setState new editorstate 不会改变状态。

import React, {Component} from 'react';

import {Editor, EditorState,getDefaultKeyBinding,moveFocusToEnd, KeyBindingUtil,getContentStateFragment, SelectionState, Modifier, CompositeDecorator} from 'draft-js';

const storage = {
  "Abm7" : "Abminorseventh"
}
export default class MyEditor extends Component {

  constructor(props) {
    super(props);

    this.state = { editorState: EditorState.createEmpty(), lastOffset:0 };
    this.focus = () => this.refs.editor.focus();
    this.logState = () => console.log(this.state.editorState.toJS());
  }

  onChange(editorState) {
    this.setState({editorState});
  }

  handleBeforeInput(e) {
    if(e === ' ') {

      const { editorState } = this.state;
      const content = editorState.getCurrentContent();
      const selection = editorState.getSelection();
      const end = selection.getEndOffset();

      const block = content.getBlockForKey(selection.getAnchorKey());
      const word = block.getText();
      const result = word.slice(this.state.lastOffset, selection.getEndOffset());
      const newSelection = new SelectionState({
          anchorKey: block.getKey(),
          anchorOffset: 0,
          focusKey: block.getKey(),
          focusOffset: 2
      })
      const contentReplaced = Modifier.replaceText(
                content,
                newSelection,
                "**")
      const editorStateModified = EditorState.push(
         editorState,
         contentReplaced,
         'replace-text'
      );

      this.setState({lastOffset: selection.getEndOffset(), editorState:editorStateModified})
      return true;
    }else {
      return false;
    }
  }

  prompt(e) {
    e.preventDefault();
    const {editorState} = this.state;
    const content = editorState.getCurrentContent();
    const selection = editorState.getSelection();
    const block = editorState.getCurrentContent().getBlockForKey(selection.getAnchorKey());

    let text = block.getText().slice(selection.getStartOffset(), selection.getEndOffset());

    const contentReplaced = Modifier.replaceText(
              content,
              selection,
              storage[text])
    const editorStateModified = EditorState.push(
       editorState,
       contentReplaced,
       'replace-text'
    );
    console.log(editorStateModified.getCurrentContent())
    this.setState({editorState:editorStateModified})
  }

  render() {
    const styles = {
      root: {
        fontFamily: '\'Helvetica\', sans-serif',
        padding: 20,
        width: 600,
      },
      editor: {
        border: '1px solid #ccc',
        cursor: 'text',
        minHeight: 80,
        padding: 10,
      },
      button: {
        marginTop: 10,
        textAlign: 'center',
      },
      buttons: {
          marginBottom: 10,
      },
    };
    return (
      <div style={styles.root}>
        <div style={styles.buttons}>
                <button
                  onMouseDown={(e)=>{this.prompt(e)}}
                  style={{marginRight: 10}}>
                  Change word
                </button>
          </div>
        <div style={styles.editor} onClick={this.focus}>
          <Editor
            editorState={this.state.editorState}
            onChange={(e)=>{this.onChange(e)}}
            handleBeforeInput={(e)=>{this.handleBeforeInput(e)}}
            placeholder="Enter some text..."
            ref="editor"
            />
        </div>
        <input
          onClick={this.logState}
          style={styles.button}
          type="button"
          value="Log State"
          />
      </div>
    );
  }

}
4

1 回答 1

1

如果您希望应用更改,该函数handleBeforeInput应该返回。"handled"它应该返回给Editor组件,因此您需要将函数按Editor原样传递给组件,如下所示:

<Editor
  ...
  handleBeforeInput={this.handleBeforeInput}
  ...
/>

参考:https ://draftjs.org/docs/api-reference-editor#handlebeforeinput

于 2020-05-05T11:03:06.203 回答