skip to Main Content

I need a React Component to show some pictures in a custom layout made out by ‘n’ number of flex layouts. Each of this flex has an array of pictures wrapped in another flex, with flex-direction: column. The goal is to achieve a layout similar to the CSS columns, but with a little more control on it.
Here’s my code:

import React, { useEffect, useState } from "react"
import { useParams } from "react-router-dom"
import useStorage from "../hooks/useStorage"
import { Column } from "./Column"

const splitInColumns = (nCols, photos) => {
  if (Array.isArray(photos)) {
    const cols = new Array(nCols).fill(null).map(() => [])
    let count = 0

    for (let i = 0; i < photos.length; i++) {
      cols[count].push(photos.pop())
      count == nCols - 1 ? (count = 0) : count++
    }

    return cols
  }
}

function Album() {
  const params = useParams()
  const [isLoading, folder] = useStorage({ type: "get-album", path: `assets/albums/${params.albumID}` })
  const [album, setAlbum] = useState([])

  useEffect(() => {
    if (Array.isArray(folder)) {
      setAlbum(splitInColumns(3, folder))
    }
  }, [folder, isLoading])

  {
    isLoading && <p>Caricamento</p>
  }

  return (
    <div>
      <div className="flex justify-center">
        <div className="flex w-5/6 h-full">
          {album.map((col, index) => (
            <Column
              key={index}
              items={col}
            />
          ))}
        </div>
      </div>
    </div>
  )
}

export default Album

The problem: I get less pictures than I actually should.
I guess the problem is the way I update the album state inside of the useEffect() hook. But shouldn’t the album state be updated everytime folder changes? Why I get less images?

2

Answers


  1. Chosen as BEST ANSWER

    The problem simply is that I'm using the pop() method to get the last item of folder, inside my splitInColumns, so I get exactly half of the items, because the useEffect reruns every time I do this (I guess).


  2. you should try changing the splitInColumns function a little bit for example :

    const splitInCOlumns = (nCol,photos) => {
    if (Array.isArray(photos)){
    const col = new Array(nCol).fill(null).map(() => []);
    
    photos.forEach((photo,index)=> {
    col[index % nCol].push(photo);
    });
    return col;
    }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search