我有一个组件
import React, { Component } from 'react'
import { EditorState, convertToRaw } from 'draft-js'
import { Editor } from 'react-draft-wysiwyg'
import 'react-draft-wysiwyg/dist/react-draft-wysiwyg.css'
import draftToHtml from 'draftjs-to-html'
import toolbarOptions from './JpuriTextEditorOptions'
export default class TextEditor extends Component {
state = {
editorState: this.props.editorState
}
componentWillReceiveProps = nextProps => {
console.warn('componentWillReceiveProps')
console.log('nextProps.editorState', nextProps.editorState)
console.log('this.props.editorState', this.props.editorState)
this.setState({editorState: nextProps.editorState})
}
onEditorStateChange = editorState => this.setState({editorState})
onBlur = () => this.props.onBlur({key: this.props.myKey, value: draftToHtml(convertToRaw(this.state.editorState.getCurrentContent()))})
render () {
return (
<Editor
wrapperClassName={this.props.wrapperClassName}
editorClassName={this.props.editorClassName}
toolbarClassName={`toolbarAbsoluteTop ${this.props.toolbarClassName}`}
wrapperStyle={this.props.wrapperStyle}
editorStyle={this.props.editorStyle}
toolbarStyle={this.props.toolbarStyle}
editorState={this.state.editorState}
onEditorStateChange={this.onEditorStateChange}
onChange={this.props.onChange}
toolbarOnFocus
toolbar={toolbarOptions}
onFocus={this.props.onFocus}
onBlur={this.onBlur}
onTab={this.props.onTab}
/>
)
}
}
我传递了一个反应性道具,this.props.editorState
然后我将其设置在内部状态以处理那里的更改。并且只有onBlur
我将更改保存到mongo db。
现在有一个问题。 每当我点击编辑器时,我都会看到componentWillReceiveProps记录几次。它发生在每次更改,因此我无法正确使用我的编辑器组件。因为每次点击和更改都会将光标重置为第一个字母。
我正在使用这个draftjs https://github.com/jpuri/react-draft-wysiwyg
库修改
该问题的更多细节。 在构造函数或componentDidMount中将状态设置为this.props.editorState正在解决初始状态的问题。 但仍然只剩下一个问题。 在另一个组件中,我有撤消重做功能,可直接与db一起使用。现在,如果我输入一些文字。模糊它我的更改保存到数据库,我可以看到文本,因为内部文本。但是,如果单击撤消按钮,文本将从db中撤消,但由于内部状态,它仍将在编辑器中可见。所以我必须刷新才能看到我的行动撤消。 使用componentWillReceiveProps解决了这个问题,但是由于某些原因,即使不更改props,每次状态更改时都会调用componentWillReceiveProps。从而带来了上述问题。
答案 0 :(得分:2)
如果您使用此组件的受控模式,则应在内部设置状态,而不是通过道具从外部设置状态。
例如,如果您在收到的每个新道具上设置状态,则没有理由使用内部状态
根据他们的DOCS,你似乎遵循他们的受控EditorState
的例子,除非你在每个新道具上覆盖你的州。
我想如果您只是从componentWillReceiveProps
中删除此行为
即设置状态:this.setState({editorState: nextProps.editorState})
它应该像预期的那样工作。
这是他们的例子:
import React, { Component } from 'react';
import { EditorState } from 'draft-js';
import { Editor } from 'react-draft-wysiwyg';
class ControlledEditor extends Component {
constructor(props) {
super(props);
this.state = {
editorState: EditorState.createEmpty(),
};
}
onEditorStateChange: Function = (editorState) => {
this.setState({
editorState,
});
};
render() {
const { editorState } = this.state;
return (
<Editor
editorState={editorState}
wrapperClassName="demo-wrapper"
editorClassName="demo-editor"
onEditorStateChange={this.onEditorStateChange}
/>
)
}
}
修改强>
作为评论的后续内容,状态初始化通常在constructor
中进行
但是当您想要异步初始化状态时,您不能也不应该在构造函数中执行它(也不能在componentWillMount
中),因为在异步操作完成时,render
方法将被调用。
最好的地方是componentDidMount
或eventHandlers,所以在你的情况下onBlur
eventHandler:
从'react'导入React,{Component};
从'draft-js'导入{EditorState};
从'react-draft-wysiwyg'导入{Editor};
class ControlledEditor extends Component {
constructor(props) {
super(props);
this.state = {
editorState: EditorState.createEmpty(),
};
}
onEditorStateChange = (editorState) => {
this.setState({
editorState,
});
};
onBlur = (event) => {
// do async stuff here and update state
};
render() {
const { editorState } = this.state;
return (
<Editor
editorState={editorState}
wrapperClassName="demo-wrapper"
editorClassName="demo-editor"
onEditorStateChange={this.onEditorStateChange}
onBlur={this.onBlur}
/>
)
}
}