Javascript 反应流星、反应道具和内部状态
我有一个组件Javascript 反应流星、反应道具和内部状态,javascript,mongodb,reactjs,meteor,draftjs,Javascript,Mongodb,Reactjs,Meteor,Draftjs,我有一个组件 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' imp
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}
/>
)
}
}
import React,{Component}来自“React”
从“草稿js”导入{EditorState,convertToRaw}
从“react draft wysiwyg”导入{Editor}
导入“react draft wysiwyg/dist/react draft wysiwyg.css”
从“draftjs到html”导入draftToHtml
从“/jpuritextededitoroptions”导入工具栏选项
导出默认类TextEditor扩展组件{
状态={
编辑状态:this.props.editorState
}
componentWillReceiveProps=nextProps=>{
console.warn('componentWillReceiveProps')
log('nextrops.editorState',nextrops.editorState)
console.log('this.props.editorState',this.props.editorState)
this.setState({editorState:nextrops.editorState})
}
onEditorStateChange=editorState=>this.setState({editorState})
onBlur=()=>this.props.onBlur({key:this.props.myKey,value:draftToHtml(convertToRaw(this.state.editorState.getCurrentContent())))
渲染(){
返回(
)
}
}
我给它传递了一个被动的道具,this.props.editorState
然后我将其设置在内部状态中,以处理那里的更改。只有onBlur
I将更改保存到mongo db
现在有一个问题。
每当我点击编辑器时,我会看到componentWillReceiveProps日志几次。每次更改都会发生这种情况,因此我无法正确使用编辑器组件。因为每次单击和更改,光标都会重置为第一个字母
我正在使用这个draftjs库
编辑
问题的更多细节。
在构造函数或componentDidMount中将状态设置为this.props.editorState可以解决初始状态的问题。
但仍然只剩下一个问题。
在另一个组件中,我有直接与db一起工作的undo-redo功能。现在如果我输入一些文本。模糊它我的更改被保存到数据库中,由于内部文本,我可以看到文本。但是,如果单击“撤消”按钮,文本将从数据库中撤消,但是由于内部状态的原因,它仍将在编辑器中可见。因此,我必须刷新才能看到我的操作撤消。
使用componentWillReceiveProps解决了这个问题,但是由于某种原因,即使props没有更改,每次状态更改时都会调用componentWillReceiveProps。因此带来了上述问题。如果您正在使用此组件的受控模式,那么您应该在内部设置状态,而不是通过道具从外部设置状态。
例如,如果您在收到的每个新道具上设置状态,则没有理由使用内部状态。
根据他们的观点,你似乎在效仿他们的受控
EditorState
示例,除非你在每个新道具上覆盖了你的状态。我认为,如果您将此行为从
组件中删除,则将接收道具
i、 e设置状态:this.setState({editorState:nextrops.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}
/>
)
}
}
如果你正在为收到的每个新道具设置状态,那么为什么要使用内部状态呢?亲爱的Sag1v,我的问题正是关于使用外部道具和内部状态。我使用数据库中的外部道具并将其设置为初始状态。然后,当用户开始键入时,我不想在用户键入时保存到数据库中。因此,当用户完成键入时,我将更改保存到数据库中,即onBlur
。这正是我需要用外部道具再次初始化状态的时候,但这样我仍然只有内部状态。如果用户刷新浏览器怎么办?他输入的文本不会丢失吗?在onBlur
处理程序中,您可以更新db
上的内容(如我的注释“在这里执行异步操作并更新状态”),是的,但我通过一个道具传递数据库的保存状态,因此我需要以某种方式使用该道具设置状态,否则它将始终为空。您可以在两个位置执行此操作:1。服务器初始状态的组件didmount
。2.更新服务器后,在ajax回调中的onBlur
事件处理程序上(不过,您可能会有与从UI更新服务器状态相同的状态,因此我认为没有必要再次更新UI,因为它的状态相同)。
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}
/>
)
}
}