Reactjs:如何编写一个方法来处理组件创建和卸载

时间:2018-03-30 23:19:10

标签: javascript reactjs

因此,假设有一个显示2个子组件的组件:文档列表所选文档。默认情况下,仅当从列表中选择文档时,才会呈现所选文档组件。当我从列表中选择一个新文档时,我也希望这一切都有效。

state保存文档内容并负责所选文档呈现,所以我想我要将其设置为 null 在处理列表项选择的方法中,以便卸载先前创建的子组件。像这样(摘自父类):

 handleResultListItemClick(docname) {
    if (this.state.sectioncontainer != null) this.setState({sectioncontainer: null},()=>{console.log("muhoo");});
    var selected_doc = this.state.resultlist.filter((doc) => {
      return docname === doc.properties.title;
    });
    this.setState({sectioncontainer: selected_doc[0].content.sections},()=>{console.log("boohoo");});
  }

...

render() {
  return (

    ...

    {this.state.sectioncontainer != null && <SectionContainer listOfSections={this.state.sectioncontainer}/>}
  );
}

唯一的问题是状态处理反应不够快(或者某些东西),因为在同一方法中放置state无效及其新值设置会导致ReactDOM没有变化。 使用上面的代码,将在父组件首次呈现时创建组件,但在列表中选择新文档后,结果不会发生任何更改。

我应该如何以有效和优雅的方式实现这一点?

我在官方反应文档中发现了这个:ReactDOM.unmountComponentAtNode(container)。这是唯一的方法吗?如果是,我怎么能得到这个container'名字'?

修改

根据答案并更多地思考问题,我必须解释更多的背景。

正如金达罗解释的那样,我理解为什么不需要在基本级别卸载子组件,但也许我的问题有点复杂。那我为什么要卸下这个孩子?

文档由几个子部分组成,因此传递给子组件的文档对象是一个对象数组。并且以下列方式基于此数组动态生成文档(摘自负责显示文档的SectionContainer类):

  buildSectionContainer() {
    return this.props.listOfSections.map((section, index) =>
      {
        if (section.type === 'editor') return (
          <QuillEditor
            key={index}
            id={section.id}
            modules={modules}
            defaultValue={section.content}
            placeholder={section.placeholder}
          />
        );
        else if (section.type === 'text') return (
         <div key={index}>{section.value}</div>
        );
      }
    );
  }

  render() {
    return (
      <div>
        {this.buildSectionContainer()}
      </div>
    );
  }

SectionContainer获取对象数组,并根据这些部分的类型从中生成文档。问题是,当在父组件中选择不同的文档时,不会更新这些部分。只有当一个更大的长度数组传递给子组件时,我才会看到更改。就像第一次选择的doc有一个包含2个元素的数组,然后新选择的doc有3个元素的截面数组,第三个部分被添加到先前存在的2个,但前两个部分保持不变。 这就是为什么我最好卸载子组件并创建一个新组件。

当然,我可能会再次错过一些基本的东西。也许与反应处理列表有关。我只是不知道是什么。

EDIT2:

好的,我发现我使用QuillEditor组件的方式存在问题。我只是不知道是什么。 :)文档更新,只有QuillEditors的内容不会。

1 个答案:

答案 0 :(得分:2)

你当前的解决方案实际上没有做任何事情的原因是因为React的状态更新是批处理的,这样,当一次调用setState时,React“组合”了所有这些的结果。 “不够快”并不是一个问题,因为React只执行必要的工作。

// this...
this.setState({ message: 'hello', secret: 123 })
this.setState({ message: 'world' })

// ...becomes this
this.setState({ message: 'world', secret: 123 })

但这种行为与手头的问题并没有太大关系。只要您的UI是州的直接翻译 - &gt;用户可以根据状态更新UI。

class Example extends React.Component {
  state = {
    documentList: [], // assuming this comes from the server
    document: null,
  }

  // consider making this function accept a document object instead,
  // then you could leave out the .find(...) call
  handleDocumentSelection = documentName => {
    const document = this.state.documentList.find(doc => doc.name === documentName)
    this.setState({ document })
  }

  render() {
    const { document } = this.state
    return (
      <div>
        <DocumentList
          documents={this.state.documentList}
          onDocumentSelection={this.handleDocumentSelection}
        />

        {/*
          consider having this component accept the entire document
          to make it a little cleaner
        */}
        {document && <DocumentViewer document={document.content.sections} />}
      </div>
    )
  }
}