Managing subcomponents that are not in the DOM subtree

Consider a component that needs to manage subcomponents that are not children in their own DOM tree, but must be added to a top-level document.

A typical example would be an autocomplete field, which should display autocomplete matches in the floating menu below the input field. A floating menu must be added as a child of a document element in order to avoid any "overflows: hidden" constants in the tree that would prevent it from showing. The floating menu must be deleted after it is no longer used.

In this case, the logical approach seems to be to mount the component in an arbitrary div and then unmount it when it is no longer needed. However, this leads to an interesting state flow problem when events are used to trigger such unmounts.

Here is an excerpt from my current code to illustrate the problem:

componentDidUpdate: function(prevProps, prevState) {
  if (prevState.matches !== this.state.matches) {
    if (this._floater) {
      this._floater.remove();
      this._floater = null;
    }

    if (this.state.matches.length > 0) {
      this._floater = Floater.create(
        <Floater
          parentElement={this.getDOMNode()}
          open={true}>
          <SelectableList
            items={this.state.matches}
            limit={10}
            onSelectionChange={this.handleSelectionChange}/>
        </Floater>
      );
    }
  }
},

handleSelectionChange: function(items) {
  this.setState({matches: [], selectedItem: items[0]});
},

Here Floateris a common component that may contain any other component; he establishes himself absolute, positions himself and so on. Floater.create()- a convenient method for creating a float component and inserting it into a document.

Floater.remove() as follows:

remove: function() {
  var self = this;
  if (this.isMounted()) {
    window.setTimeout(function() {
      React.unmountComponentAtNode(self.getDOMNode().parentNode);
    }, 10);
  }
},

, , - . - SelectableList, handleSelectionChange , remove(), , . , .

, ?

+4

Source: https://habr.com/ru/post/1529344/


All Articles