反応の達人の簡単な質問;)
React.Children.only はトップレベルAPIの1つであり、react-redux(<Provider />
)およびReact Router(<Router />
)コンテキストとしてストア/ルーターを挿入します。この背後にある理由は何ですか、単にreturn props.children
? JSXと何か関係があるようですか?
編集:説明しないでくださいwhatはReact.Children.onlyです、私はwhyprops.childrenの代わりにそれを使用します。
docs で指摘されているように
子に子が1つしかないことを検証し(React要素)、それを返します。そうでない場合、このメソッドはエラーをスローします。
では、なぜprops.children
を使用するだけで役立つのでしょうか?
主な理由は、エラーをスローするため、開発フロー全体が停止するため、スキップできません。
これは、特にonlyの子を持つというルールを実施する便利なユーティリティです。
もちろん、propTypes
を使用することもできますが、コンソールに警告が表示されるだけです。
React.Children.only
の使用例の1つは、1つの論理的な子コンポーネントで構成される特定の宣言インターフェイスを適用することです。
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>
);
}
}
次のように使用できます。
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>
)
}
}
これが役に立てば幸いです。
Before React 16 、コンポーネントのrenderメソッドは要素の配列を返すことができませんでした。独自のマークアップを導入しないコンポーネントを実装する場合、単一の子のみを受け入れるための選択:
// 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;
これで、単にreturn props.children
、呼び出し元が配列要素にkey
sを含めることを要求する、またはreturn <>{props.children}</>
、配列を返すことを避けるために Fragment を使用します。
const DisplayIf = ({children, condition}, {uniforms}) =>
condition(uniforms) ? <>{children}</> : nothing;
DisplayIf.contextTypes = BaseField.contextTypes;