Skip to content

react media

Created: 2018-03-26 08:53:49 -0700 Modified: 2018-03-26 09:30:28 -0700

This is a library that can render based on a media query using the function-as-child render pattern:

class App extends React.Component {
render() {
return (
<div>
<Media query="(max-width: 599px)">
{matches =>
matches ? (
<p>The document is less than 600px wide.</p>
) : (
<p>The document is at least 600px wide.</p>
)
}
</Media>
</div>
);
}
}

As you can see above, you have a <Media> component, and its child has to be a function that has a single argument for whether the query is matched.

For more usage notes, e.g. specifying the query as a JSON object, check their docs.

Dynamically pick parent element (or parent props) without changing children

Section titled Dynamically pick parent element (or parent props) without changing children

In my specific scenario, I had a <Scrollbars> element that needed to pass a specific prop only on desktop. I wanted something like this:

Desktop:

<Scrollbars
prop1={desktopProp1}
prop2={desktopProp2}
>
<CommonChild1/>
<CommonChild2/>
</Scrollbars>

Mobile:

<Scrollbars
prop1={mobileProp1}
prop2={mobileProp2}
>
<CommonChild1/>
<CommonChild2/>
</Scrollbars>

HiDeoo suggested a solution that worked out well:

const childContent = (
<Fragment>
<CommonChild1/>
<CommonChild2/>
</Fragment>
);
<Media query={someMediaQuery}>
{matches => {
const baseProps = {
commonProp1,
commonProp2,
};
const desktopProps = baseProps;
const mobileProps = {
mobileSpecificProp1,
mobileSpecificProp2,
...baseProps,
};
const props = matches ? mobileProps : desktopProps;
return (
<Scrollbars {...props}>
{childContent}
</Scrollbars>
);
}}
</Media>

If I ever wanted a different parent instead of just different props (e.g. “Scrollbars” for desktop, “Scrollbars2” for mobile), then I should probably just return something different based on the contents of “matches”, e.g. the code that you see in the introduction section of this note. However, if you really want to make a generic wrapping element, you can do something like this snippet that HiDeoo linked in:

// wrapper.js

export default ({ name, element }) => <element.type {...element.props}>Hello {name}!</element.type>

// anotherfile.js

<Wrapper element={<span style={{ color: 'red' }} />} name="HiDeo" />