diff --git a/README.md b/README.md index 14c0bc6..b108c6f 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,87 @@ You can find the library on `window.ReactMedia`. ## Basic usage -Render a `` component with a `query` prop whose value is a valid [CSS media query](https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries). The `children` prop should be a function whose only argument will be a boolean flag that indicates whether the media query matches or not. +### queries + +Render a `` component with a `queries` prop whose value is an object, +where each value is a valid +[CSS media query](https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries). +The `children` prop should be a function whose argument will be an object with the +same keys as your `queries` object, and whose values are booleans indicating whether +each query matches. + +```jsx +import React, { Fragment } from 'react'; +import Media from 'react-media'; + +class App extends React.Component { + render() { + return ( +
+ + {matches => ( + + {matches.small &&

I am small!

} + {matches.medium &&

I am medium!

} + {matches.large &&

I am large!

} +
+ )} +
+
+ ); + } +} +``` + +### query + +Alternatively, if you only need to match against a single media query, the `query` prop provides a less-verbose approach. +More documentation about the difference betwen `query` and `queries` can be found below. + +```jsx +import React, { Fragment } from 'react'; +import Media from 'react-media'; + +class App extends React.Component { + render() { + return ( +
+ + ( +

I am small!

+ )} + /> +
+ ); + } +} +``` + +## `query` vs `queries` + +The `queries` prop was added to allow for multiple media queries to be matched without excessive nesting or other +workarounds. The `query` prop was retained out of recognition that a single query covers many use cases, and there +is already a lot of usage that would be a pain to migrate. + +The salient points: + +* **You cannot use them together**: if you do, the component will throw an error. This is to avoid confusion around +precedence. +* **The render methods differ slightly**: for the `queries` prop, the `render` and child JSX methods will render if +**at least one** of the given queries is matched. The `query` prop renders if the given query matches. + + +## `queries` + +In addition to passing a valid media query string, the `queries` +prop will also accept an object of objects whose forms are similar to +[React's built-in support for inline style objects](https://facebook.github.io/react/tips/inline-styles.html) +in e.g. `
`. These objects are converted to CSS +media queries via [json2mq](https://github.com/akiran/json2mq/blob/master/README.md#usage). ```jsx import React from 'react'; @@ -45,9 +125,21 @@ class App extends React.Component { render() { return (
- +

These two Media components are equivalent

+ + {matches => - matches ? ( + matches.small ? ( +

The document is less than 600px wide.

+ ) : ( +

The document is at least 600px wide.

+ ) + } +
+ + + {matches => + matches.small ? (

The document is less than 600px wide.

) : (

The document is at least 600px wide.

@@ -60,15 +152,17 @@ class App extends React.Component { } ``` -## Render props +Keys of media query objects are camel-cased and numeric values automatically get the `px` suffix. See the [json2mq docs](https://github.com/akiran/json2mq/blob/master/README.md#usage) for more examples of queries you can construct using objects. + +### Render props There are three props which allow you to render your content. They each serve a subtly different purpose. |prop|description|example| |---|---|---| -|render|Only invoked when the query matches. This is a nice shorthand if you only want to render something for a matching query.|`

I matched!

} />`| -|children (function)|Receives a single boolean element, indicating whether the media query matched. Use this prop if you need to render something when the query doesn't match.|`{matches => matches ?

I matched!

:

I didn't match

}
`| -|children (react element)|If you render a regular React element within ``, it will render that element when the query matches. This method serves the same purpose as the `render` prop, however, you'll create component instances regardless of whether the query matches or not. Hence, using the `render` prop is preferred ([more info](https://github.com/ReactTraining/react-media/issues/70#issuecomment-347774260)).|`

I matched!

`| +|render|Only invoked when **at least one** of the queries matches. This is a nice shorthand if you only want to render something for a matching query.|`

I matched!

} />`| +|children (function)|Receives an object of booleans whose keys are the same as the `queries` prop, indicating whether each media query matched. Use this prop if you need to render different output for each of specified queries.|`{matches => matches.foo ?

I matched!

:

I didn't match

}
`| +|children (react element)|If you render a regular React element within ``, it will render that element when **at least one** of the queries matches. This method serves the same purpose as the `render` prop, however, you'll create component instances regardless of whether the queries match or not. Hence, using the `render` prop is preferred ([more info](https://github.com/ReactTraining/react-media/issues/70#issuecomment-347774260)).|`

I matched!

`| ## `query` @@ -111,9 +205,19 @@ class App extends React.Component { Keys of media query objects are camel-cased and numeric values automatically get the `px` suffix. See the [json2mq docs](https://github.com/akiran/json2mq/blob/master/README.md#usage) for more examples of queries you can construct using objects. +### Render props + +There are three props which allow you to render your content. They each serve a subtly different purpose. + +|prop|description|example| +|---|---|---| +|render|Only invoked when the query matches. This is a nice shorthand if you only want to render something for a matching query.|`

I matched!

} />`| +|children (function)|Receives a single boolean element, indicating whether the media query matched. Use this prop if you need to render something when the query doesn't match.|`{matches => matches ?

I matched!

:

I didn't match

}
`| +|children (react element)|If you render a regular React element within ``, it will render that element when the query matches. This method serves the same purpose as the `render` prop, however, you'll create component instances regardless of whether the query matches or not. Hence, using the `render` prop is preferred ([more info](https://github.com/ReactTraining/react-media/issues/70#issuecomment-347774260)).|`

I matched!

`| + ## `onChange` -You can specify an optional `onChange` prop, which is a callback function that will be invoked when the status of the media query changes. This can be useful for triggering side effects, independent of the render lifecycle. +You can specify an optional `onChange` prop, which is a callback function that will be invoked when the status of the media queries changes. This can be useful for triggering side effects, independent of the render lifecycle. ```jsx import React from 'react'; @@ -124,9 +228,9 @@ class App extends React.Component { return (
- matches + matches.small ? alert('The document is less than 600px wide.') : alert('The document is at least 600px wide.') } @@ -150,14 +254,14 @@ initialState = {
Render me below medium breakpoint.} /> Render me above medium breakpoint.} />
; @@ -165,11 +269,7 @@ initialState = { ## `targetWindow` -An optional `targetWindow` prop can be specified if you want the `query` to be evaluated against a different window object than the one the code is running in. This can be useful if you are rendering part of your component tree to an iframe or [a popup window](https://hackernoon.com/using-a-react-16-portal-to-do-something-cool-2a2d627b0202). See [this PR thread](https://github.com/ReactTraining/react-media/pull/78) for context. - -## Compared to react-responsive - -If you're curious about how react-media differs from [react-responsive](https://github.com/contra/react-responsive), please see [this comment](https://github.com/ReactTraining/react-media/issues/70#issuecomment-347774260). +An optional `targetWindow` prop can be specified if you want the `queries` to be evaluated against a different window object than the one the code is running in. This can be useful if you are rendering part of your component tree to an iframe or [a popup window](https://hackernoon.com/using-a-react-16-portal-to-do-something-cool-2a2d627b0202). See [this PR thread](https://github.com/ReactTraining/react-media/pull/78) for context. ## About