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.
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.
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 key
s 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;