yarn add react-sizes
npm install react-sizes
React Sizes is a high-order component with a high performance that transform window sizes (width and height) into props.
You can check inside your component, for example, if user's window is less than 480 pixels of width, and add a custom
content.
It can be very powerful for when you need to display different content for mobile and desktop. But it's not limited to this case. Just use that at your needs.
import React, { Component } from 'react';
import Sizes from 'react-sizes';
class MyComponent extends Component {
render() {
return (
<div>{this.props.isMobile ? 'Is Mobile' : 'Is Not Mobile'}</div>
);
}
}
const mapSizesToProps = ({ width }) => ({
isMobile: width < 480,
});
export Sizes(mapSizesToProps)(MyComponent);
You can play with this example here.
import React from 'react';
import Sizes from 'react-sizes';
@Sizes(({ width }) => ({ isMobile: width < 480 }))
class MyComponent extends Component {
render() {
return (
<div>{this.props.isMobile ? 'Is Mobile' : 'Is Not Mobile'}</div>
);
}
}
export default MyComponent;
import React from 'react';
import Sizes from 'react-sizes';
const MyComponent = ({ isMobile }) => (
<div>{isMobile ? 'Is Mobile' : 'Is Not Mobile'}</div>
);
const mapSizesToProps = ({ width }) => ({
isMobile: width < 480,
});
export Sizes(mapSizesToProps)(MyComponent);
import React from 'react';
import Sizes from 'react-sizes';
import { withState, compose } from 'recompose';
const enhancer = compose(
withState('counter', 'setCounter', 0),
Sizes(({ width }) => ({ isMobile: width < 480 })),
);
const MyComponent = enhancer(({ isMobile, counter, setCounter }) => (
<div>
<div>
Count: {counter} <button onClick={() => setCounter(n => n + 1)}>Increment</button>
</div>
<div>{isMobile ? 'Is Mobile' : 'Is Not Mobile'}</div>
</div>
));
export default MyComponent;
- const mapSizesToProps = ({ width }) => ({
- isMobile: width < 480,
- });
+ const mapSizesToProps = sizes => ({
+ isMobile: Sizes.isMobile(sizes),
+ });
You can check all our presets selectors at our main code src/Sizes.js
.
Sizes.isMobile = ({ width }) => width < 480;
Sizes.isTablet = ({ width }) => width >= 480 && width < 1024;
Sizes.isDesktop = ({ width }) => width >= 1024;
Sizes.isGtMobile = (sizes) => !Sizes.isMobile(sizes);
Sizes.isGtTablet = (sizes) => Sizes.isDesktop(sizes);
Sizes.isStTablet = (sizes) => Sizes.isMobile(sizes);
Sizes.isStDesktop = (sizes) => !Sizes.isStDesktop(sizes);
Sizes.isTabletAndGreater = (sizes) => !Sizes.isMobile(sizes);
Sizes.isTabletAndSmaller = (sizes) => !Sizes.isStDesktop(sizes);
If it don't fit to your needs, you can create your own selectors.
// utils/sizes/selectors.js
export const isntDesktop = ({ width }) => width < 1024;
export const backgroundColor = ({ width }) => width < 480 ? 'red' : 'green';
// your component
import { isntDesktop, backgroundColor } from 'utils/sizes/selectors';
const mapSizesToProps = sizes => ({
canDisplayMobileFeature: isntDesktop(sizes),
backgroundColor: backgroundColor(sizes),
});
sizes
argument is an object withwidth
andheight
properties and represents DOM window width and height.
Window resize event listener is grouped at one global listener only. So you can have as many components as you want using Sizes hoc, which will not have multiple resize listeners, but only one that will dispatch for all instances.
Don't worry, Sizes handles componentWillUnmount
to remove unnecessary callbacks.
When each component unmounted, it unsubscribe for global dispatches, and when last component is unmounted,
the listener is removed.
By now the listener callback is hardcoded as throttle function of 200ms. Because of having a global listener, we have a limitation on changing this behavior. I don't see it as tradeoff, and I think it can have good workarounds. Then, for the future, I intend to work to bring a solution to this important customization.
sizes
argument is an object with width
and height
of DOM window.
const mapSizesToProps = sizes => {
console.log(sizes) // { width: 1200, height: 720 } (example)
};
In pratice, it is a callback that return props that will injected into your Component.
const mapSizesToProps = function(sizes) {
const props = {
backgroundColor: sizes.width < 700 ? 'red' : 'green',
};
return props;
};
But you can simplify this to stay practical and elegant.
const mapSizesToProps = ({ width }) => ({
backgroundColor: width < 700 ? 'red' : 'green',
});
You can help improving this project sending PRs and helping with issues.
Also you ping me at Twitter