skip to Main Content

The following code is raising an error:

{index % 2 === 0 && <div className='my-class'>}

Unexpected token, expected "," (9:14)


import AnotherComponent  from './Anothercomponent.jsx'

export default function CurrentComponent({ datas, onChangeValue }) {
  
  return (
    <section>
      {datas.map((data, index) => (
        {index % 2 === 0 && <div className='my-wrapper'>}
        <AnotherComponent/>
        {index % 2 === 0 && </div>}
      ))}
    </section>
  );
}

the goal is to get this result:

<section>
  <div class="my-class">
    <AnotherComponent/>
    <AnotherComponent/>
  </div>
  <div class="my-class">
    <AnotherComponent/>
    <AnotherComponent/>
  </div>
</section>

Could you help please?

3

Answers


  1. You can’t render a open and close element like that with a condition.

    First of all, the return of a map can only return a single DOM element, so you’ll need to wrap it in a div, or React.Fragment.

    But you still need to change the way you wrap it in a div.

    Consider the following were we use an inline if statement to choose between

    • Wrapping <AnotherComponent/> in a <div>
    • Just render <AnotherComponent/> without a parent
    export default function CurrentComponent({ datas, onChangeValue }) {
        return (
            <section>
                {datas.map((data, index) => (
                    {
                        (index % 2 === 0)
                            ? <div className='my-wrapper'><AnotherComponent/></div>
                            : <AnotherComponent/>
                    }
                ))}
            </section>
        );
    }   
    

    You could also define a Wrapper component that will be the div or an empty Fragment:

    return (
        <section>
            {datas.map((data, index) => {
                const Wrapper = (index % 2 === 0) ? 'div' : React.Fragment;
                return (
                    <Wrapper>
                        <AnotherComponent/>
                    </Wrapper>
                )
            }}
        </section>
    );
    

    A small demo showing the second example in a runnable react snippet:

    const Example = () => {
      
        {/* Render <Foo /> 20 times */}
        return [...Array(20)].map((e, i) => <Foo index={i} />);
    }
    
    // Foo is rendered without a parent, unless (index % 2 === 0), then Foo is wrapped in a <em>
    // <em> is styled with lightblue text
    const Foo = ({ index }) => {
    
        const Wrapper = (index % 2 === 0) ? 'em' : React.Fragment;
        
        return <Wrapper>{`Index --> ${index}`}</Wrapper>;
    }
    
    ReactDOM.render(<Example />, document.getElementById("react"));
    div { display: flex; flex-direction: column; }
    em { color: lightblue; }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
    <div id="react"></div>
    Login or Signup to reply.
  2. In JSX, a conditional rendering is applicable on an Element and not with a single element tag.

    <>
    {
        (index % 2 === 0) ? (
              <div className='my-class'>
              ...
              </div>
              : <AnotherComponent />
        )
    }
    </>
    
    Login or Signup to reply.
  3. As others have stated, the issue is you can’t render a partial element.

    {index % 2 === 0 && <div className='my-wrapper'>}
    

    will cause an error because the div element has no closing tag, react needs the entire component in a single expression.

    For your case, you can do something like this

    import AnotherComponent  from './Anothercomponent.jsx'
    
    function renderMapItem(data, index) {
      // ideally this would be a unique value from the data
      // something like data.id, we can use index for now
      const key = index;
    
      if (index % 2 === 0) {
        return (
          <div className='my-wrapper' key={key}>
            <AnotherComponent/>
          </div>
        );
      }
    
      return <AnotherComponent key={key}/>;
    }
    
    export default function CurrentComponent({ datas, onChangeValue }) {
      return (
        <section>
          {datas.map(renderMapItem)}
        </section>
      );
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search