2

我有一个需要多个文本输入的应用程序,并且为了格式化和自定义,我选择draft-js了我的编辑器,但是我遇到了一个非常令人困惑的输入问题。

当我在编辑器中键入时,我最近按下的键会打印在编辑器的开头,将我的整个输入颠倒过来,就好像插入符号总是在该行的第一个索引处。

我有 3 个编辑器,每个都有一个 onChange,它使用当前的编辑器更新一个 redux 存储contentState。当页面被重新渲染时,每个编辑器都会被渲染,它们各自的contentState转换为EditorState.

这是我的代码:

main.js

render() {

    /* Each Editor has a similar block as below */

    let coverEditorState = EditorState.createEmpty()
    let coverContentState = _.get(data, 'details.message.cover.contentState')

    if (typeof coverContentHTML != "undefined"){
        coverEditorState = EditorState.createWithContent(coverContentState)
    }

    return (
        ...
        <Composer
            editorState={coverEditorState}
            onChange={this._handleCoveringLetterChange.bind(this)}
        />
        ...
    )
}

作曲家.js

class Composer extends Component {
    constructor() {
        super()
        this.state = { editorState: EditorState.createEmpty(), styleMap: {} }
    }

    componentWillReceiveProps( nextProps ) {
        this.setState({ editorState: nextProps.editorState })
    }

    onChange( editorState ) {

        let nextState = Object.assign({}, this.state, { editorState })

        let currentContentState = editorState.getCurrentContent()

        let changeObject = {
            contentState: currentContentState
        }

        this.setState(nextState)
        this.props.onChange(changeObject)
    }

    render() {
        return (
            <Editor 
                editorState={this.state.editorState}
                onChange={this.onChange.bind(this)}
            />
        )
    }
}

我尝试过返回SelectionState以及ContentState,将两者结合起来,然后重新渲染,但这只会导致更多的问题和错误。

4

2 回答 2

1

我刚刚遇到(并解决了)一个类似的问题。

如果您遇到与我相同的问题,那是因为对状态的调用setState实际上对状态的更新进行了排队,并且在调用this.props.onChange. 可以理解的是,这似乎draft.js失控了。

尝试改变:

this.setState(nextState)
this.props.onChange(changeObject)

至:

this.setState(nextState, () => { 
    this.props.onChange(changeObject); 
});

这将确保在调用父onChange回调之前更新状态。

于 2016-10-10T10:28:04.127 回答
0

我无法从您提供的代码中真正看到,但听起来您的问题是您在每次更改时都在重新创建 EditorState (使用EditorState.createEmpty()or )。EditorState.createWithContetnt()那是行不通的,因为它只是恢复内容——而不是光标位置、选择等。

我解决它的方法是我EditorState只创建一次,即如果它不存在。然后,在每次更改时,我都会EditorState正常更新,同时将 保存contentState到我们的例子中的数据库。这里重要的是您不要使用contentState来创建新的EditorState.

所以下次EditorState不存在时,它会使用EditorState.createWithContent(contentStateFromDB).

于 2016-10-07T09:20:05.137 回答