Closed iammerrick closed 6 years ago
oh that's interesting. i always assumed that the error was being thrown from the component but i guess it's getting sent from the compiler...
<Only children={<div>one</div><div>two</div>}>
Failed to compile.
Error in ./src/App.js
Syntax error: Adjacent JSX elements must be wrapped in an enclosing tag (9:38)
7 | return (
8 | <div className="App">
> 9 | <Only children={<div>one</div><div>two</div>}>
| ^
10 | </div>
11 | );
12 | }
Interesting.
Admittedly, trying to come up with examples for this seem contrived to me. Do you have any that illustrate the need for Children.only?
thanks for helping me clarify this :)
I didn't understand the use of Children.only(children)
yet. 😞
That's my fault. I've done a terrible job of explaining it.
The practical use of Children.only
is that you can create a component that doesn't introduce new DOM elements. This is a pretty good description of the use case: https://github.com/facebook/react/issues/4424#issuecomment-122607192
@chantastic I have a bunch of components that doesn't emit DOM, e.g. https://github.com/smalldots/smalldots/blob/v0.33.0/src/Toggler.js
Maybe I can replace:
return this.props.children(api) || null
with:
return Children.only(this.props.children(api))
.
The reason for || null
is that sometimes the consumer may render "false":
<Toggler>{({ toggled, toggle }) => !toggled && <button>...</button>}</Toggler>
And as it's a render callback, I really want to enforce one child, so Children.only()
is semantic.
Does this PR make it any clearer? https://github.com/chantastic/reactpatterns.com/pull/19
@hnordt that seems right to me. I'm not using any places where i don't control what children
are. but yah, i just use it any place i want to wrap something with lifecycle functionality, don't want need an HoC, and don't want to emit extraneous DOM.
@chantastic I would recommend that:
There are times you'll want a component to have only some lifecycle logic and delegate the rendering to the parent component (render callbacks are an example of that behavior).
In this case, to enforce the rendering of only one child and throws an error otherwise, you can use the function React.Children.only
:
class SomeLifeCycleWrapper extends React.Component {
componentDidMount() {
console.log("I mounted but have no DOM.")
}
render() {
return React.Children.only(this.props.children)
}
}
In cases where you're working with state or context, prefer higher-order components or render callbacks.
I don't agree with this because actually render callbacks are good candidates to use Children.only
.
I think we can even rename that pattern to rendering delegation 😝
The section about helpful errors on children pass through when using
React.Children.only
. What helpful errors? I can't really see anything on React's documentation and would love to understand this better!