skip to Main Content

basically I need to generate a

<div class=row></div>

every 3rd record. how can I do this?

Some info:

  • using the sample code below, I’m getting an "unexpected token" error
  • HTML renders fine if I remove the getReminder calls
  • instead of "return index & divisor", I tried "return 1" and I get the same error

this is my sample JSX

const cars = ['Saab', 'Volvo', 'BMW', 'Toyota', 'Honda', 'Subaru']

export default function App() {
    const getRemainder = function (index, divisor) {
        return index % divisor
    }

    return (
        <>
            <div className="container-fluid">
                {cars.map((x, index) => (
                    {getRemainder(index, 3) == 0 && <div className='row'>}
                    <h4>
                        car: {x} | index: {index}
                    </h4>
                    {getRemainder(index, 3) == 2 && </div>}
                ))}
            </div>
        </>
    )
}

this woud be my ideal rendered HTML using the sample code above

<div class="container-fluid">
    <div class="row">
        <div class="col">Saab</div>
        <div class="col">Volvo</div>
        <div class="col">BMW</div>
   </div>
   <div class="row">
       <div class="col">Toyota</div>
       <div class="col">Honda</div>
       <div class="col">Subaru</div>
   </div>
</div>

2

Answers


  1. JSX are not strings. Therefore you can’t pretend you are concatenating strings. You are instead building a tree of objects.

    Your bug is here:

    {getRemainder(index, 3) == 0 && <div className='row'>}
    

    This should throw an error since when JSX processes this expression it will find the div to be unclosed.

    This is also invalid:

    {getRemainder(index, 3) == 2 && </div>}
    

    The div has no matching opening tag.

    What you can do instead is refactor the list creation logic into its own function:

    const splitGroup = (items, columns) => {
        let group = [];
    
        while (items.length > 0) {
            group.push(
            <div class="row">
                items.splice(0, columns).map(x => {
                    return <div class="col">{x}</div>
                })
            </div>
            )
        }
    
        return group;
    }
    

    then simply do:

    return (
        <div className="container-fluid">
            {splitGroup(cars, 3)}
        </div>
    )
    

    Alternative code

    If you’re not familiar with .splice() you can do the same with traditional for loops:

    const splitGroup = (items, columns) => {
        let group = [];
    
        while (items.length > 0) {
            let row = [];
    
            for (let i=0; i<columns && items.length > 0; i++) {
                row.push(<div class="col">{items.shift()}</div>
            }
    
            group.push(
                <div class="row">{row}</div>
            )
        }
    
        return group;
    }
    
    Login or Signup to reply.
  2. You are getting

    "unexpected token" error

    because {getRemainder(index, 3) == 0 && <div className='row'>} is invalid JSX, the element div should have a closing tag.

    You can achieve the required output by slicing the array into an array of arrays of the three items.

    Here is the updated code that achieve the required output. I also abstracted the row into a separate component.

    const cars = ["Saab", "Volvo", "BMW", "Toyota", "Honda", "Subaru"];
    
    const transformedCars = [];
    for (let i = 0; i < cars.length; i += 3) {
      transformedCars.push(cars.slice(i, i + 3));
    }
    
    export default function App() {
      const getRemainder = function (index, divisor) {
        return index % divisor;
      };
    
      return (
        <>
          <div className="container-fluid">
            {transformedCars.map((cars, index) => (
              <CarsRow key={index} cars={cars} />
            ))}
          </div>
        </>
      );
    }
    
    const CarsRow = ({ cars }) => {
      return (
        <div className="row">
          {cars.map((car, index) => (
            <h4>
              car: {car} | index: {index}
            </h4>
          ))}
        </div>
      );
    };
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search