15

I'm using the Material-UI version 1 to make the grid UI in my React application. I want to make the grid responsive. The GridList component API has cols props, which by default is 2.

For example, it could looks like this below.

<GridList cols={1} spacing={32} className="list"></GridList>

Can I dynamically change the props? Or are there any other ways to make it responsive?

sflow
  • 655
  • 2
  • 8
  • 18

5 Answers5

34

U can use the layout breakpoints provide by MUI to toggle GridList or GridListTile cols property. The code will look like this:

...
import withWidth, { isWidthUp } from '@material-ui/core/withWidth';
...

const MyComponent = props => {
  const getGridListCols = () => {
    if (isWidthUp('xl', props.width)) {
      return 4;
    }

    if (isWidthUp('lg', props.width)) {
      return 3;
    }

    if (isWidthUp('md', props.width)) {
      return 2;
    }

    return 1;
  }

  return(
    ...
    <GridList spacing={15} cellHeight={400} cols={getGridListCols()}>
      {
        myItemsArray.map(item => (
          <GridListTile key={item} cols={1}>
            <FooBar />
          </GridListTile>
        ))
      }
    </GridList>
    ...
  );
};

...

export default withWidth()(MyComponent);
Morlo Mbakop
  • 3,518
  • 20
  • 21
  • Would this update the number of columns when the screen is resized? – Edo Dec 19 '19 at 17:56
  • Yes, this will update the number of columns when the screen is resized because the HOC (higher order component) `withWidth` will request a re-render when the browser width changes. Note: You can now use a [`useWidth`](https://material-ui.com/components/use-media-query/#migrating-from-withwidth) React hook as suggested here. – Nick Merrill Jun 14 '20 at 14:38
6

You can choose the cols value depending on the width (xs, sm, md, lg, xl), look at this example where 1 column is set for smaller screens.

import React from "react";
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import compose from 'recompose/compose';

// @material-ui/core components
import withStyles from "@material-ui/core/styles/withStyles";
import withWidth from '@material-ui/core/withWidth';
import GridList from '@material-ui/core/GridList';
import GridListTile from '@material-ui/core/GridListTile';
import GridListTileBar from '@material-ui/core/GridListTileBar';

const styles = theme => ({ });

class MyComponent extends React.Component {
    render() {
        const { classes, currentUser, images, width } = this.props;

        let columns = width === 'xs' || width === 'sm'  ? 1 : 2;

        return (
            <div className={classes.root}>
                <GridList cellHeight={180} cols={columns} className={classes.gridList}>
                    {images.map(image => (
                    <GridListTile key={image.id}>
                        <img src={ image.path } />
                        <GridListTileBar
                            title={ image.name }
                        />
                    </GridListTile>
                    ))}
                </GridList>
            </div>
        );
    }
}

MyComponent.propTypes = {
    currentUser: PropTypes.object,
    images: PropTypes.array.isRequired
};

function mapStateToProps(state) {
    return {
        currentUser: state.user.currentUser
    };
}

export default compose(
  withStyles(styles, {
    name: 'MyComponent',
  }),
  withWidth(),
  connect(mapStateToProps),
)(MyComponent);
Felipe Pereira
  • 11,410
  • 4
  • 41
  • 45
4

As of Material-UI v4.4, you can use useMediaQuery React hook in conjunction with theme.breakpoints.up:

import useMediaQuery from '@material-ui/core/useMediaQuery';

function MyComponent() {
  const matches = useMediaQuery(theme => theme.breakpoints.up('sm'));

  return <span>{`theme.breakpoints.up('sm') matches: ${matches}`}</span>;
}

⚠️ There is no default theme support, you have to inject it in a parent theme provider.

Hendy Irawan
  • 20,498
  • 11
  • 103
  • 114
1

I just came across this issue and while using @morlo's answer, I did a mistake and it started showing a js error but strangely it also made it responsive! And by responsive, I mean that it shows a horizontal scrolling which is common in mobiles.

So I removed that code and used different values and cols={0} worked!

Perhaps it is not documented but it works actually.

Also worth mentioning some other settings that I used along:

<GridList style={{
        width: '100%',
        maxHeight: 320,
        flexWrap: 'nowrap'
}} cols={0} cellHeight={'auto'}>
...
</GridList>
M.Imran Mamda
  • 394
  • 1
  • 2
  • 13
-3

When you say you want to make the grid responsive, do you perhaps mean adding more items dynamically? If not, by default Material-UI is responsive (meaning your viewport is dynamically sized depending on the device you view on), and depending on your GridList properties (like cols, rows, spacing etc) you can determine the style. If you have a look at https://material-ui-next.com/demos/grid-list/ there are a few examples to get you started.

Nita
  • 149
  • 12
  • @sflow did you find the above helpful in solving your problem? – Nita Jun 14 '18 at 10:02
  • 3
    It wasn't helpful, as it didn't answer what he was asking for. He was asking how he could dynamically change the `cols` property :) – oligofren Mar 13 '19 at 13:34