I'm trying to render multiple child components depending on state however I'm only able to return one child component (SyntaxError: Adjacent JSX elements must be wrapped in an enclosing tag)
Each child component passes the same props, how could this code be kept DRY?
Works
export default ({changeState, myState, handleClick}) => (     <Navigation>             <span>Navigation</span>             <button onClick={() => changeState()}>Navigation</button>             { myState ?                 <NavigationItem handleClick={handleClick} title={'#Link-1'} />               : null             }     </Navigation> )   Don't
export default ({changeState, myState, handleClick}) => (     <Navigation>             <h1>Navigation</h1>             <button onClick={() => changeState()}>Navigation</button>             { myState ?                 <NavigationItem handleClick={handleClick} title={'#Link-1'} />                 <NavigationItem handleClick={handleClick} title={'#Link-2'} />                 <NavigationItem handleClick={handleClick} title={'#Link-3'} />               : null             }     </Navigation> ) 
                React allows us to render one component inside another component. It means, we can create the parent-child relationship between the 2 or more components.
In Vue and React, we can only render one element. Even if we have multiple elements to render, there can only be a single root element. This means if we want to render two or more elements, we have to wrap them in another element or component.
7 Ways to Implement Conditional Rendering in React Applications | DigitalOcean.
Directly we can't return more than one elements.
Possible Solutions:
1- Either you need to wrap all the elements in a div or any other wrapper element.
2- We can return an array of multiple elements also, So put all the items in an array, and return the array.
Like this:
{myState ?     [         <NavigationItem handleClick={handleClick} title={'#Link-1'} />,         <NavigationItem handleClick={handleClick} title={'#Link-2'} />,         <NavigationItem handleClick={handleClick} title={'#Link-3'} />     ]   : null }   Check this example:
let b = true ? [1,2,3,4]: null;    console.log('b = ', b);  This will throw error:
let b = true? 1 2 3 4: null;    console.log('b = ', b);  You can also use <Fragment> from ReactJS: https://reactjs.org/docs/fragments.html
The problem about wrapping all the elements with a <div>, is that you are adding more elements to the DOM, and sometimes it's impossible (for example, when you are rendering a <td> or <tr> inside a <table>. So, here is where <Fragment> comes to help us.
Just wrap all those elements in a <Fragment> and it'll be enough. Meaning:
{ myState &&   <Fragment>     <NavigationItem handleClick={handleClick} title={'#Link-1'} />     <NavigationItem handleClick={handleClick} title={'#Link-2'} />     <NavigationItem handleClick={handleClick} title={'#Link-3'} />   </Fragment> }   Anyways, this another "Conditional Rendering" approach is better in "code readability" sense: https://medium.com/@BrodaNoel/conditional-rendering-in-react-and-jsx-the-solution-7c80beba1e36
It basically proposes the use of a <Conditional> element, like:
<Conditional if={myState}>   <NavigationItem handleClick={handleClick} title={'#Link-1'} />,   <NavigationItem handleClick={handleClick} title={'#Link-2'} />,   <NavigationItem handleClick={handleClick} title={'#Link-3'} /> </Conditional>   ^ This looks better for my eyes :D
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With