Take a simple ponent:
function MyComponent({ children }) {
return children;
}
This works:
ReactDOM.render(<MyComponent><span>Hello</span></MyComponent>, document.getElementById('stage'));
but this doesn't (I removed the <span/>
):
ReactDOM.render(<MyComponent>Hello</MyComponent>, document.getElementById('stage'));
because React tries to call render
on the string:
Uncaught TypeError: inst.render is not a function
On the other hand, this works fine:
ReactDOM.render(<p>Hello</p>, document.getElementById('stage'));
How do I make <MyComponent/>
behave like <p/>
?
Take a simple ponent:
function MyComponent({ children }) {
return children;
}
This works:
ReactDOM.render(<MyComponent><span>Hello</span></MyComponent>, document.getElementById('stage'));
but this doesn't (I removed the <span/>
):
ReactDOM.render(<MyComponent>Hello</MyComponent>, document.getElementById('stage'));
because React tries to call render
on the string:
Uncaught TypeError: inst.render is not a function
On the other hand, this works fine:
ReactDOM.render(<p>Hello</p>, document.getElementById('stage'));
How do I make <MyComponent/>
behave like <p/>
?
5 Answers
Reset to default 4If you're using React 16.2 or higher, you can do this using React fragments:
const MyComponent = ({children}) => <>{children}</>
If your editor doesn't support fragment syntax, this will also work:
const MyComponent = ({children}) =>
<React.Fragment>{children}</React.Fragment>
Keep in mind that you're still creating & returning a ponent (of type MyComponent) as far as React is concerned - it just doesn't create an additional DOM tag. You'll still see a <MyComponent>
tag in the React Debug Tools, and MyComponent's return type is still a React element (React.ReactElement).
Well the difference is <p>
is an html element and MyComponent
is a React Component.
React ponents need to render/return either a single ponent or a single html element.
'Hello'
is neither.
You need at least one top-level HTML element. Your ponent can't really just output a string, that's not how React works.
The simplest solution is to simply make your MyComponent
wrap it's output in a span or div.
function MyComponent({ children }) {
return <span>{ children }</span>;
}
Currently, in a ponent's render, you can only return one node; if you have, say, a list of divs to return, you must wrap your ponents within a div, span or any other ponent.
source
And what you are returning is not a root node. You are returning a react ponent that is returning a string where it should be returning an HTML element.
You can either pass your string already wrapped with an HTML element (like you already did in your example) or you can wrap your string in a HTML element inside your "MyComponent" like this
function MyComponent({ children }) {
return <span>{ children }</span>;
}
React can render either React ponents (classes) or HTML Tags (strings). Any HTML tag is by convention lowercase where a Component is Capitalized. Every React ponent has to render exactly one Tag (or null). To answer your question: you cannot.
In the example above, you render what's given with the children
attribute where this will render the tag inside or a string that is not valid.