Skip to content

Instantly share code, notes, and snippets.

@insanrizky
Last active June 19, 2019 07:27
Show Gist options
  • Save insanrizky/5902f2f99639a41e68b6c4c65aa102bd to your computer and use it in GitHub Desktop.
Save insanrizky/5902f2f99639a41e68b6c4c65aa102bd to your computer and use it in GitHub Desktop.
Responsive Compound Component
import React from 'react';
import Responsive, { NotMatches, Matches } from '#src/common/Responsive';
class Test extends React.Component {
render() {
return (
<div className="p-4">
<Responsive width="max-width: 768px">
<h3>Header</h3>
<hr />
<NotMatches>
<div> Nggak cocok nih </div>
</NotMatches>
<Matches>
<div> cocok nih </div>
</Matches>
</Responsive>
</div>
);
}
}
export default Test;
import React, { Component, createContext } from 'react';
import { array, object, oneOfType, string } from 'prop-types';
import { viewPort } from './viewport';
const Context = createContext({
isMobile: false,
});
const { Provider, Consumer } = Context;
const NotMatches = ({ children }) => {
return <Consumer>{({ isMobile }) => !isMobile && children}</Consumer>;
};
NotMatches.propTypes = {
children: oneOfType([array, object]),
};
const Matches = ({ children }) => (
<Consumer>{({ isMobile }) => isMobile && children}</Consumer>
);
Matches.propTypes = {
children: oneOfType([array, object]),
};
// Define our viewport into variable
const myViewPort = viewPort();
class Responsive extends Component {
state = {
isMobile: myViewPort.matches,
};
// Get aware if props change from users
static getDerivedStateFromProps(props, state) {
const query = viewPort(props.width).matches;
return {
isMobile: query,
};
}
componentDidMount() {
myViewPort.addListener(this.checkWidth);
}
componentWillUnmount() {
myViewPort.removeListener(this.checkWidth);
}
checkWidth = () => {
const { width } = this.props;
this.setState({
isMobile: viewPort(width).matches,
});
};
render() {
const { children } = this.props;
return (
<Provider
value={{
isMobile: this.state.isMobile,
}}
>
{children}
</Provider>
);
}
}
Responsive.propTypes = {
children: oneOfType([array, object]),
width: string,
};
export default Responsive;
export { Context, NotMatches, Matches };
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment