reactjsreact-bootstrapbootstrap-grid

How to dynamically create a new row?


I'm using react-bootstrap and I'm wondering if it's possible to dynamically go to the next row based on code. Let me show you what I'm trying to do :

// components/WeatherList.js

import React from 'react'
import { Col, Row } from 'react-bootstrap'
import WeatherCard from './WeatherCard'

const WeatherList = ({weathers}) => {
    console.log("e")
    console.log(weathers)
    return (
        <Row>
           {weathers.list.map(({dt, main, weather}) => (
                <Col key={dt}>
                    <WeatherCard
                    dt={dt * 1000} 
                    temp_min={main.temp_min} 
                    temp_max={main.temp_max} 
                    humidity={main.humidity}
                    temp={main.temp}
                    main={weather[0].main} 
                    city={weathers.city.name}
                    country={weathers.city.country}
                  />
                </Col>
            ))} 
        </Row>
    )
}

export default WeatherList;

I get up to 5 prediction per day (so 5 cards), but if I only get 2 prediction I want to go to a new line for the next day. On the picture you can see, I'd like to dynamically create a new row when the day change :

enter image description here

How can I do that ?


Solution

  • I would try something like this to filter out the weather objects into groups of days:

    import React, { useEffect, useState } from 'react'
    import { Col, Row } from 'react-bootstrap'
    import WeatherCard from './WeatherCard'
    
    const WeatherList = ({weathers}) => {
        console.log("e")
        console.log(weathers)
        
        const [weathersDays, setWeathersDays] = useState([]); // An array of weather objects for a day
    
        useEffect(()=>{
            let previousDay = null;
            tempDays = []
            returnDays = []
            // Loop through weathers to split by day
            weathers.list.map(({dt, main, weather}) => {
                    const currentDate = new Date()
                    currentDate.setTime(dt*1000);
                    const currentDay = currentDate.getDay() // An integer representing the day
                    if (previousDay == null) {
                        // The first day (Edge Case), just push to the current day
                        previousDay = currentDay;
                        tempDays.push({dt, main, weather})
                    }
                    else if (previousDay == currentDay) {
                        // Same day, so push to list for current day
                        tempDays.push({dt, main, weather})
                    }
                    else {
                        // This is a new day, push list of old days and start a new tempDays list
                        returnDays.push(tempDays);
                        previousDay = currentDay;
                        tempDays = [];
                        tempDays.push({dt, main, weather});
                    }
                })
            // Catch the last group of days if not empty
            if (tempDays.length > 0){
                returnDays.push(tempDays);
            }
            setWeathersDays(returnDays);
        },[weathers])
    
        return (
            <>
                {weathersDays.map(weatherDay => {
                <Row>
                    {weatherDay.map(({dt, main, weather}) => (
                        <Col key={dt}>
                            <WeatherCard
                            dt={dt * 1000} 
                            temp_min={main.temp_min} 
                            temp_max={main.temp_max} 
                            humidity={main.humidity}
                            temp={main.temp}
                            main={weather[0].main} 
                            city={weathers.city.name}
                            country={weathers.city.country}
                        />
                        </Col>
                    ))} 
                </Row>
                })
                } 
            </>
        )
    }
    
    export default WeatherList;