npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

react-media-responsive

v0.1.4

Published

Provider and media query wrapper for your React components

Downloads

6

Readme

react-media-responsive

Usable, but still under development

There will be examples both vanilla React and also together with Redux, but I'd like to write more test cases and add some more coverage. In the meantime feel free to use this at your own risk. At this point, feedback is very welcomed, as well as contributions. For that, please use Github issues and follow the Code of Conduct.

Motivation

Truly responsive design is tricky, and although React makes reasoning about responsive design very easy, the difficulties grow when we reuse components' presentational logic. If your components' render method are like mine, I am sure you'll be often faced complexities when rendering the same component for different resolutions. Often you ought to leave out some menu items, or render a complete separate child depending on your device's orientation.

While there are some other projects already solving this issue similarly, I found a few problems, or outdated approaches and other stuff leading to code repetition I wasn't happy working with.

This new approach is the result of taking a different perspective on react-responsive. I wanted more flexibility on how to play within the render() method, and the possibility to reduce computational time as I dealt with responsiveness within my React components.

If we think of UI responsiveness as part of the state tree, then heavily reusable components become easy to reason about by encouraging the reduction of boilerplate and conditional statements that offer a powerful approach to complicated cases. Think of how easy then becomes, to pass prop value to a child component, and encapsulate other behaviors indirectly related to a media query... Flexibility is served!

How it works

Glad you ask! Because this project has been inspired a great deal by react-redux. As a result, you'll probably find the next piece of code very familiar...

import React from 'react'
import SampleApp from './SampleApp.js'
import { ResponsiveProvider } from './react-media-responsive'

const media = {
  tablet: {
    screen: true,
    minWidth: 768,
    maxWidth: 1024
  },
  fromTablet: {
    minWidth: '768px'
  },
  retina: {
    minResolution: '2dppx'
  },
  notLandscape: {
    orientation: 'portrait'
  }
}

export default (
  <ResponsiveProvider media={media}>
    <SampleApp />
  </ResponsiveProvider>
)

Good responsive designs are thought using breakpoints, orientation and a variety of other properties. Therefore, you'll want to define these onto a media object, and pass it down to the <ResponsiveProvider>.

This wrapper uses your app's context to keep the state tree of media queries up to date, adding one listener for each of the named breakpoints/changes you want to define. These named keys are your way into the responsive world.

We'll see next how this approach facilitates not only writing code to deal with your responsive design cases, but also to be able to optimize each individual component using shouldComponentUpdate().

Usage

Just like react-redux, when we need responsiveness, we need to make that component aware of changes. Upon wrapping, a component subscribes to the global responsiveStore that lives in the context, and will wait for matched media queries' changes.

import React, { Component } from 'react';
import { responsive } from 'react-media-responsive';

class SampleApp extends Component {
  render() {
    const { responsive } = this.props;

    return (
      <div className={responsive.tablet ? 'isTablet' : ''} style={{fontSize: responsive.retina ? 22 : 16}}>
        {responsive.tablet ? (
          <span>
            I am a tablet
            {responsive.notLandscape ? (
              <span>, and I am NOT in landscape mode</span>
            ) : (
              <span>, and I am in landscape mode</span>
            )}
          </span>
        ) : (
          <span>I am NOT a tablet {responsive.fromTablet && '. However I am WIDER!'}</span>
        )}
      </div>
    );
  }
  /**
   * Comment out the next method to get an instant optimization boost, while resizing your browser window.
   * Note that store updates are already debounced, so use this method mindfully when you want that extra bit of performance.
   */
  //shouldComponentUpdate(nextProps) {
  //  const { fromTablet } = this.props.responsive;

  //  if (fromTablet !== nextProps.responsive.fromTablet) {
  //    return true;
  //  }
  //  return false;
  //}
}
export default responsive()(SampleApp);

Important note

The connector/wrapper should be the closest to the actual Component. If you'd use react-redux's connect() method and then wrap it with responsive(), react-redux would be made aware of new properties passed every time a media query matches, which is a small performance penalty you can easily avoid:

BAD:

export default responsive()(connect()(SampleApp));

GOOD:

export default connect()(responsive()(SampleApp));

Defining media queries

Embracing this project's brother repository, please refer to this complete list with all possible shorthands and value types https://github.com/wearefractal/react-responsive/blob/master/src/mediaQuery.js#L9

Any numbers given as a shorthand will be expanded to px (1234 will become '1234px')

Options

  • withRef {Boolean} exposes the wrapper component with refs so that you may access it.
  • only {Array} string values passed to this array will implement shouldComponentUpdate and trigger only a state change on the WrappedComponent when some value in it matches, ignoring any other updates in values passed to the ResponsiveProvider.

Server rendering

Server rendering can be done by passing static values through the values property in the provider:

export default (
  <ResponsiveProvider media={media} values={{width: 1024, minResolution: '2dppx'}}>
    <SampleApp />
  </ResponsiveProvider>
)

Browser Support

Out of the box

With Polyfills

Just like react-responsive, we encourage you to use polyfills whenever extended browser support is required: