react-media vs react-responsive
响应式设计库
react-mediareact-responsive类似的npm包:

响应式设计库

响应式设计库用于帮助开发者创建适应不同屏幕尺寸和设备的用户界面。它们提供了一种简便的方法来管理媒体查询和条件渲染,从而确保应用在各种设备上的可用性和美观性。使用这些库可以显著提高开发效率,减少手动编写媒体查询的需求,同时保持代码的可读性和可维护性。

npm下载趋势

3 年

GitHub Stars 排名

统计详情

npm包名称
下载量
Stars
大小
Issues
发布时间
License
react-media02,424-87 年前MIT
react-responsive07,17256.6 kB51 年前MIT

功能对比: react-media vs react-responsive

API设计

  • react-media:

    react-media提供了一个简单且直观的API,允许开发者通过组件的props来定义媒体查询。它的使用方式非常灵活,可以轻松地在组件中实现条件渲染。

  • react-responsive:

    react-responsive的API相对复杂,支持更多的功能,比如自定义断点和嵌套媒体查询。它允许开发者在更高层次上控制响应式设计,适合需要更复杂布局的应用。

灵活性

  • react-media:

    react-media提供了基本的响应式功能,适合简单的应用场景。它的灵活性主要体现在对媒体查询的支持上,但在复杂场景下可能会显得不足。

  • react-responsive:

    react-responsive提供了更高的灵活性,支持多种媒体查询条件和自定义断点,适合需要复杂布局和多设备支持的应用。

性能

  • react-media:

    react-media在性能方面表现良好,尤其是在处理简单的媒体查询时。由于其简单的实现,渲染性能不会受到显著影响。

  • react-responsive:

    react-responsive在性能上可能会稍显复杂,特别是在处理大量媒体查询时。开发者需要注意优化,以避免不必要的重渲染。

学习曲线

  • react-media:

    react-media的学习曲线相对平缓,开发者可以快速上手并实现基本的响应式设计。

  • react-responsive:

    react-responsive的学习曲线稍陡峭,特别是对于需要掌握其复杂API和功能的开发者来说。

社区支持

  • react-media:

    react-media的社区相对较小,文档和示例可能不如其他更流行的库丰富。

  • react-responsive:

    react-responsive拥有更大的社区支持,文档详尽,示例丰富,开发者可以更容易找到解决方案和最佳实践。

如何选择: react-media vs react-responsive

  • react-media:

    选择react-media如果你需要一个简单的API来处理媒体查询,并且希望在组件中直接使用条件渲染。它适合那些希望快速实现响应式设计的开发者。

  • react-responsive:

    选择react-responsive如果你需要更强大的功能,比如支持自定义断点、服务端渲染和更复杂的条件渲染需求。它适合那些需要更高灵活性和可扩展性的项目。

react-media的README

react-media Travis npm package

react-media is a CSS media query component for React.

A <Media> component listens for matches to a CSS media query and renders stuff based on whether the query matches or not.

Installation

Using npm:

$ npm install --save react-media

Then, use as you would anything else:

// using ES modules
import Media from 'react-media';

// using CommonJS modules
var Media = require('react-media');

The UMD build is also available on unpkg:

<script src="https://unpkg.com/react-media"></script>

You can find the library on window.ReactMedia.

Basic usage

queries

Render a <Media> component with a queries prop whose value is an object, where each value is a valid CSS media query. 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.

import React, { Fragment } from 'react';
import Media from 'react-media';

class App extends React.Component {
  render() {
    return (
      <div>
        <Media queries={{
          small: "(max-width: 599px)",
          medium: "(min-width: 600px) and (max-width: 1199px)",
          large: "(min-width: 1200px)"
        }}>
          {matches => (
            <Fragment>
              {matches.small && <p>I am small!</p>}
              {matches.medium && <p>I am medium!</p>}
              {matches.large && <p>I am large!</p>}
            </Fragment>
          )}
        </Media>
      </div>
    );
  }
}

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.

import React, { Fragment } from 'react';
import Media from 'react-media';

class App extends React.Component {
  render() {
    return (
      <div>
        <Media query="(max-width: 599px)" render={() =>
          (
            <p>I am small!</p>
          )}
        />
      </div>
    );
  }
}

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 in e.g. <div style>. These objects are converted to CSS media queries via json2mq.

import React from 'react';
import Media from 'react-media';

class App extends React.Component {
  render() {
    return (
      <div>
        <h1>These two Media components are equivalent</h1>

        <Media queries={{ small: { maxWidth: 599 } }}>
          {matches =>
            matches.small ? (
              <p>The document is less than 600px wide.</p>
            ) : (
              <p>The document is at least 600px wide.</p>
            )
          }
        </Media>

        <Media queries={{ small: "(max-width: 599px)" }}>
          {matches =>
            matches.small ? (
              <p>The document is less than 600px wide.</p>
            ) : (
              <p>The document is at least 600px wide.</p>
            )
          }
        </Media>
      </div>
    );
  }
}

Keys of media query objects are camel-cased and numeric values automatically get the px suffix. See the json2mq docs 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.

propdescriptionexample
renderOnly 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>} />
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>
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).<Media queries={{ ... }}><p>I matched!</p></Media>

query

In addition to passing a valid media query string, the query prop will also accept an object, similar to React's built-in support for inline style objects in e.g. <div style>. These objects are converted to CSS media queries via json2mq.

import React from 'react';
import Media from 'react-media';

class App extends React.Component {
  render() {
    return (
      <div>
        <h1>These two Media components are equivalent</h1>

        <Media query={{ maxWidth: 599 }}>
          {matches =>
            matches ? (
              <p>The document is less than 600px wide.</p>
            ) : (
              <p>The document is at least 600px wide.</p>
            )
          }
        </Media>

        <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>
    );
  }
}

Keys of media query objects are camel-cased and numeric values automatically get the px suffix. See the json2mq docs 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.

propdescriptionexample
renderOnly 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>} />
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>
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).<Media query="..."><p>I matched!</p></Media>

onChange

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.

import React from 'react';
import Media from 'react-media';

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

Server-side rendering (SSR)

If you render a <Media> component on the server, it will match by default. You can override the default behavior by setting the defaultMatches prop.

When rendering on the server you can use the defaultMatches prop to set the initial state on the server to match whatever you think it will be on the client. You can detect the user's device by analyzing the user-agent string from the HTTP request in your server-side rendering code.

initialState = {
  device: 'mobile' // add your own guessing logic here, based on user-agent for example
};

<div>
  <Media
    queries={{ medium: "(max-width: 500px)" }}
    defaultMatches={{ medium: state.device === 'mobile' }}
    render={() => <Text>Render me below medium breakpoint.</Text>}
  />

  <Media
    queries={{ medium: "(min-width: 501px)" }}
    defaultMatches={{ medium: state.device === 'desktop' }}
    render={() => <Text>Render me above medium breakpoint.</Text>}
  />
</div>;

targetWindow

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. See this PR thread for context.

About

react-media is developed and maintained by React Training. If you're interested in learning more about what React can do for your company, please get in touch!