Skip to content

Commit 5dc1a74

Browse files
authored
Merge pull request #119 from tstirrat15/118-add-queries-block
Start rewriting docs towards `queries`
2 parents 2e6497a + a832017 commit 5dc1a74

File tree

1 file changed

+119
-19
lines changed

1 file changed

+119
-19
lines changed

README.md

+119-19
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,87 @@ You can find the library on `window.ReactMedia`.
3535

3636
## Basic usage
3737

38-
Render a `<Media>` 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.
38+
### queries
39+
40+
Render a `<Media>` component with a `queries` prop whose value is an object,
41+
where each value is a valid
42+
[CSS media query](https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries).
43+
The `children` prop should be a function whose argument will be an object with the
44+
same keys as your `queries` object, and whose values are booleans indicating whether
45+
each query matches.
46+
47+
```jsx
48+
import React, { Fragment } from 'react';
49+
import Media from 'react-media';
50+
51+
class App extends React.Component {
52+
render() {
53+
return (
54+
<div>
55+
<Media queries={{
56+
small: "(max-width: 599px)",
57+
medium: "(min-width: 600px) and (max-width: 1199px)",
58+
large: "(min-width: 1200px)"
59+
}}>
60+
{matches => (
61+
<Fragment>
62+
{matches.small && <p>I am small!</p>}
63+
{matches.medium && <p>I am medium!</p>}
64+
{matches.large && <p>I am large!</p>}
65+
</Fragment>
66+
)}
67+
</Media>
68+
</div>
69+
);
70+
}
71+
}
72+
```
73+
74+
### query
75+
76+
Alternatively, if you only need to match against a single media query, the `query` prop provides a less-verbose approach.
77+
More documentation about the difference betwen `query` and `queries` can be found below.
78+
79+
```jsx
80+
import React, { Fragment } from 'react';
81+
import Media from 'react-media';
82+
83+
class App extends React.Component {
84+
render() {
85+
return (
86+
<div>
87+
<Media query="(max-width: 599px)" render={() =>
88+
(
89+
<p>I am small!</p>
90+
)}
91+
/>
92+
</div>
93+
);
94+
}
95+
}
96+
```
97+
98+
## `query` vs `queries`
99+
100+
The `queries` prop was added to allow for multiple media queries to be matched without excessive nesting or other
101+
workarounds. The `query` prop was retained out of recognition that a single query covers many use cases, and there
102+
is already a lot of usage that would be a pain to migrate.
103+
104+
The salient points:
105+
106+
* **You cannot use them together**: if you do, the component will throw an error. This is to avoid confusion around
107+
precedence.
108+
* **The render methods differ slightly**: for the `queries` prop, the `render` and child JSX methods will render if
109+
**at least one** of the given queries is matched. The `query` prop renders if the given query matches.
110+
111+
112+
## `queries`
113+
114+
In addition to passing a valid media query string, the `queries`
115+
prop will also accept an object of objects whose forms are similar to
116+
[React's built-in support for inline style objects](https://facebook.github.io/react/tips/inline-styles.html)
117+
in e.g. `<div style>`. These objects are converted to CSS
118+
media queries via [json2mq](https://github.com/akiran/json2mq/blob/master/README.md#usage).
39119

40120
```jsx
41121
import React from 'react';
@@ -45,9 +125,21 @@ class App extends React.Component {
45125
render() {
46126
return (
47127
<div>
48-
<Media query="(max-width: 599px)">
128+
<h1>These two Media components are equivalent</h1>
129+
130+
<Media queries={{ small: { maxWidth: 599 } }}>
49131
{matches =>
50-
matches ? (
132+
matches.small ? (
133+
<p>The document is less than 600px wide.</p>
134+
) : (
135+
<p>The document is at least 600px wide.</p>
136+
)
137+
}
138+
</Media>
139+
140+
<Media queries={{ small: "(max-width: 599px)" }}>
141+
{matches =>
142+
matches.small ? (
51143
<p>The document is less than 600px wide.</p>
52144
) : (
53145
<p>The document is at least 600px wide.</p>
@@ -60,15 +152,17 @@ class App extends React.Component {
60152
}
61153
```
62154

63-
## Render props
155+
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.
156+
157+
### Render props
64158

65159
There are three props which allow you to render your content. They each serve a subtly different purpose.
66160

67161
|prop|description|example|
68162
|---|---|---|
69-
|render|Only invoked when the query matches. This is a nice shorthand if you only want to render something for a matching query.|`<Media query="..." render={() => <p>I matched!</p>} />`|
70-
|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.|`<Media query="...">{matches => matches ? <p>I matched!</p> : <p>I didn't match</p>}</Media>`|
71-
|children (react element)|If you render a regular React element within `<Media>`, 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)).|`<Media query="..."><p>I matched!</p></Media>`|
163+
|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.|`<Media queries={{ foo: ... }} render={() => <p>I matched!</p>} />`|
164+
|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.|`<Media queries={{ foo: ... }}>{matches => matches.foo ? <p>I matched!</p> : <p>I didn't match</p>}</Media>`|
165+
|children (react element)|If you render a regular React element within `<Media>`, 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)).|`<Media queries={{ ... }}><p>I matched!</p></Media>`|
72166

73167
## `query`
74168

@@ -111,9 +205,19 @@ class App extends React.Component {
111205

112206
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.
113207

208+
### Render props
209+
210+
There are three props which allow you to render your content. They each serve a subtly different purpose.
211+
212+
|prop|description|example|
213+
|---|---|---|
214+
|render|Only invoked when the query matches. This is a nice shorthand if you only want to render something for a matching query.|`<Media query="..." render={() => <p>I matched!</p>} />`|
215+
|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.|`<Media query="...">{matches => matches ? <p>I matched!</p> : <p>I didn't match</p>}</Media>`|
216+
|children (react element)|If you render a regular React element within `<Media>`, 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)).|`<Media query="..."><p>I matched!</p></Media>`|
217+
114218
## `onChange`
115219

116-
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.
220+
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.
117221

118222
```jsx
119223
import React from 'react';
@@ -124,9 +228,9 @@ class App extends React.Component {
124228
return (
125229
<div>
126230
<Media
127-
query="(max-width: 599px)"
231+
query={{ small: "(max-width: 599px)" }}
128232
onChange={matches =>
129-
matches
233+
matches.small
130234
? alert('The document is less than 600px wide.')
131235
: alert('The document is at least 600px wide.')
132236
}
@@ -150,26 +254,22 @@ initialState = {
150254

151255
<div>
152256
<Media
153-
query="(max-width: 500px)"
154-
defaultMatches={state.device === 'mobile'}
257+
queries={{ medium: "(max-width: 500px)" }}
258+
defaultMatches={{ medium: state.device === 'mobile' }}
155259
render={() => <Text>Render me below medium breakpoint.</Text>}
156260
/>
157261

158262
<Media
159-
query="(min-width: 501px)"
160-
defaultMatches={state.device === 'desktop'}
263+
queries={{ medium: "(min-width: 501px)" }}
264+
defaultMatches={{ medium: state.device === 'desktop' }}
161265
render={() => <Text>Render me above medium breakpoint.</Text>}
162266
/>
163267
</div>;
164268
```
165269

166270
## `targetWindow`
167271

168-
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.
169-
170-
## Compared to react-responsive
171-
172-
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).
272+
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.
173273

174274
## About
175275

0 commit comments

Comments
 (0)