wake-up-neo.net

Warum nur Kinder?

Schnelle Frage nach reagierenden Gurus;)

React.Children.only ist einer seiner Top-Level-Apis und wird sehr häufig von React-redux (<Provider />) und React Router (<Router />) verwendet, um store/router als Kontext einzufügen. warum nicht einfach return props.children? Scheint etwas mit JSX zu tun?

EDIT: Bitte nicht erklären was ist React.Children.nur ich frage nach warum und benutze es anstelle von props.children, was mächtiger/flexibler erscheint.

11
Xlee

Wie in den docs

Überprüft, ob Kinder nur ein Kind (ein React-Element) haben, und gibt es zurück. Andernfalls wirft diese Methode einen Fehler aus.

Warum ist es also hilfreich, nur props.children zu verwenden?

Der Hauptgrund ist, dass ein Fehler ausgegeben wird. Dadurch wird die gesamte Entwicklerumgebung angehalten, sodass Sie ihn nicht überspringen können.

Dies ist ein praktisches Hilfsmittel, das eine bestimmte Ebene der Durchsetzung dieser bestimmten Regel erstellt, nur ein Kind zu haben.

Natürlich können Sie propTypes verwenden, aber es wird nur eine Warnung in die Konsole eingefügt, die Sie ebenso vermissen könnten.

Ein Anwendungsfall von React.Children.only kann darin bestehen, eine bestimmte deklarative Schnittstelle zu erzwingen, die aus einer logischen untergeordneten Komponente bestehen sollte:

class GraphEditorEditor extends React.Component {
  componentDidMount() {
    this.props.editor.makeEditable();
    // and all other editor specific logic
  }

  render() {
    return null;
  }
}

class GraphEditorPreview extends React.Component {
  componentDidMount() {
    this.props.editor.makePreviewable();
    // and all other preview specific logic
  }

  render() {
    return null;
  }
}

class GraphEditor extends React.Component {
  static Editor = GraphEditorEditor;
  static Preview = GraphEditorPreview;
  wrapperRef = React.createRef();

  state = {
    editorInitialized: false
  }

  componentDidMount() {
    // instantiate base graph to work with in logical children components
    this.editor = SomeService.createEditorInstance(this.props.config);
    this.editor.insertSelfInto(this.wrapperRef.current);

    this.setState({ editorInitialized: true });
  }

  render() {
    return (
      <div ref={this.wrapperRef}>
        {this.editorInitialized ?
          React.Children.only(
            React.cloneElement(
              this.props.children, 
              { editor: this.editor }
            )
          ) : null
        }
      </div>
    );
  }
}

was kann so verwendet werden:

class ParentContainer extends React.Component {
  render() {
    return (
      <GraphEditor config={{some: "config"}}>
        <GraphEditor.Editor> //<-- EDITOR mode
      </GraphEditor>
    )
  }
}

// OR

class ParentContainer extends React.Component {
  render() {
    return (
      <GraphEditor config={{some: "config"}}>
        <GraphEditor.Preview> //<-- Preview mode
      </GraphEditor>
    )
  }
}

Hoffe das hilft ein bisschen.

9
Karen Grigoryan

Vor React 16 konnte die Render-Methode einer Komponente kein Array von Elementen zurückgeben. Bei der Implementierung einer Komponente, die kein eigenes Markup eingeführt hat, hatten Sie keine andere Wahl, als nur ein Kind zu akzeptieren:

// We have to ensure that there's only one child, because returning an array
// from a component is prohibited.
const DisplayIf = ({children, condition}, {uniforms}) =>
    condition(uniforms) ? Children.only(children) : nothing;
DisplayIf.contextTypes = BaseField.contextTypes;

Jetzt können Sie einfach return props.children eingeben, wobei der Aufrufer keys in Array-Elemente einschließen muss, oder return <>{props.children}</> mit einem Fragment , um die Rückgabe eines Arrays zu vermeiden:

const DisplayIf = ({children, condition}, {uniforms}) =>
    condition(uniforms) ? <>{children}</> : nothing;
DisplayIf.contextTypes = BaseField.contextTypes;
0
BudgieInWA