How do I render a string as children in a React component?

12,421

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.

source

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>;
}
Share:
12,421
David Tuite
Author by

David Tuite

Founder and CEO of Developer Portal company roadie.io

Updated on June 16, 2022

Comments

  • David Tuite
    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
    callum over 4 years
    The '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 return ReactNode (this covers ReactFragment, ReactElement, null, strings, booleans, etc. – anything a component can render). Better still, just type the entire component function as FunctionComponent<Props>, which automatically sets the return type as ReactNode (as well as typing the props and additional optional stuff like .defaultProps, .displayName etc.).
  • Andrew Faulkner
    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.