How do I render a string as children in a React component?
Solution 1
If 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 component (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).
Solution 2
Well the difference is <p>
is an html element and MyComponent
is a React Component.
React components need to render/return either a single component or a single html element.
'Hello'
is neither.
Solution 3
You need at least one top-level HTML element. Your component 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>;
}
Solution 4
Currently, in a component's render, you can only return one node; if you have, say, a list of divs to return, you must wrap your components within a div, span or any other component.
And what you are returning is not a root node. You are returning a react component 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>;
}
David Tuite
Founder and CEO of Developer Portal company roadie.io
Updated on June 16, 2022Comments
-
David Tuite almost 2 years
Take a simple component:
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/>
? -
callum over 4 yearsThe 'Downside' in this answer is not true, unless you annotate your component function as returning a
ReactElement
, which is probably a mistake. A component function should be typed to returnReactNode
(this coversReactFragment
,ReactElement
,null
, strings, booleans, etc. – anything a component can render). Better still, just type the entire component function asFunctionComponent<Props>
, which automatically sets the return type asReactNode
(as well as typing the props and additional optional stuff like.defaultProps
,.displayName
etc.). -
Andrew Faulkner over 2 years@callum You're correct, and that downside I had listed is no longer true (it was at the time, when the feature was much newer). I've edited the answer accordingly.