Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/362.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/86.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 反应流星、反应道具和内部状态_Javascript_Mongodb_Reactjs_Meteor_Draftjs - Fatal编程技术网

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}
      />
    )
  }
}