Search code examples
javascriptreactjsslidergallery

How to display specific number of divs depending on width in react.js?


I am working on a component which is a kind of gallery with arrows to "slide" it. Basically by default it shows six dives, each of whish is an image with a brand name. I would like it to look differently depending on a screen width. It should show 6 divs (or images) on large desktops, 4 on medium and 2 on small ones. I would like an approach different than media query. I am new to react.js, so any tips and help will be appreciated.

import React from 'react';
import PropTypes from 'prop-types';

import BrandsBox from '../../common/BrandBox/BrandBox';

import styles from './Brands.module.scss';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faChevronLeft, faChevronRight } from '@fortawesome/free-solid-svg-icons';

class Brands extends React.Component {
  state = {
    activeBrands: 6,
    startBrandDisplay: 0,
  };
 
  render() {
    const { brands } = this.props;
    const { activeBrands } = this.state;
    const brandsToDisplay = brands.slice(this.state.startBrandDisplayy, activeBrands+this.state.startBrandDisplay);

    return (
      <div className={'container'}>
        <div className={styles.componentContainer}>
          <div
            onClick={() => { 
              this.setState({
                ...this.state,
                startBrandDisplay: this.state.startBrandDisplay-1
              })
            }}
    
            className={styles.swipe}>

            <FontAwesomeIcon icon={faChevronLeft} className={styles.icon} />
        
          </div>
          { brandsToDisplay.map(brands => (
            <div id ={brands.id} key={brands.id} className={styles.brandContainer}>
              <BrandsBox {...brands} />
            </div>
          ))}

          <div 
            onClick={() => { 
              this.setState({
                ...this.state,
                startBrandDisplay: this.state.startBrandDisplay+1
              })
            }}
            className={styles.swipe}>
            <FontAwesomeIcon icon={faChevronRight} className={styles.icon} />
          </div>


        </div>
      </div>
    );
  }
}
Brands.propTypes = {
  brands: PropTypes.arrayOf(
    PropTypes.shape({
      id: PropTypes.number,
      name: PropTypes.string,
      image: PropTypes.string,
    })
  ),
};

export default Brands;


Solution

  • You can create a state variable to store the device(desktop, mobile, tablet).

    And then you can add an EventListener for window resize and assign the device name to state based on the inner width.

    Now based on the device name you can specify the class to your Parent Div.

    function App() {
    
    const [device, setDevice] = useState("")
    
    function handleResize() {
    
      const width = window.innerWidth
    
    // Now check here what is the width and assign the device name 
    
    }
    
    useEffect(() => {
    window.addEventListener("resize", "handleResize");
    })
    
    }