Returning an array from a JSX function and destructuring it elsewhere

Viewed 541

Experimenting a bit with JSX at the moment and came across this idea :

I can do this:

import React from 'react'

const Test = () => {    
  return <div>Test</div>
}
export default Test

and then import this file somewhere else and do:

<Test />

Why doesn't the same work if I return arrays from my JSX files?

import React from 'react'

const Test = () => {
  let arr = [
    <div>Test 1</div>,
    <div>Test 2</div>,
  ]
  return arr;
}
export default Test

and then:

let [firstElement, secondElement] = Test();

return ( 
  <div> 
    <firstElement /> 
  </div> 
 )

In both cases, what I am trying to render is a pretty plain <div>. In the first case it's returned directly, in the second case it's destructured from an array. However, the second case doesn't work for me? Should it?

PS: I know I could do {firstElement} - but why not <firstElement />?

2 Answers

The following should work:

  let arr = [
    () => <div>Test 1</div>,
    () => <div>Test 2</div>,
  ]

What you're doing currently is calling React.createElement twice.

First you call it inside the array (<div>Test 1</div), then you return the already created element from the function, and then you render it again, by calling <firstElement/>.


Side note, firstElement should be uppercase, or else (I think) the JSX transformer will consider it a native DOM element, rather than your custom component, which will result in a throw later).

Therefore either change what's in the array into components, as stated above (() => <div>Test 1</div>), or change <firstElement /> into {firstElement}


Either way, what you're doing is quite hacky and shouldn't be anything more than a curiosity. Test should be coded as:

const Test = () => {
  const arr = [
    <div>Test 1</div>,
    <div>Test 2</div>,
  ];
  return <>{arr}</>;
}

The two divs are already react elements, an object created by React, and not components. To render them use an expression (curly braces):

const test = () => [
  <div>Test 1</div>,
  <div>Test 2</div>,
]

const [firstElement, secondElement] = test();

const Demo = () => (
  <div> 
    {firstElement}
  </div> 
)

ReactDOM.render(
  <Demo />,
  root
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

<div id="root"></div>

Related