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-redux-transition-manager

v1.3.2

Published

Higher order component to enable loading states between route transitions

Downloads

178

Readme

react-redux-transition-manager

Higher order component to enable loading states between route transitions and fetch data for the new route

peerDependencies Status Build Status Coverage Status

transiton-manager-example

Why?

There is a lot of boilerplate involved when using react router and fetching the necessary data when transitioning from route to route. This is an attempt to simplify this process with 2 primary features:

  • fetch the data that is needed for a new route before rendering the route
  • display a loading indicator in the app signifying that the new route is loading, while keeping the current route visible

inspired by https://github.com/ReactTraining/react-router/issues/2101

Import reducer into app

import the reducer to add it to the redux store. this will allow you to connect other components the fetching state of the app and allow the transition manager component to dispatch and get the information from the store during transitions

import { combineReducers } from 'redux'
import isAppFetching from 'react-redux-transition-manager/redux/is-app-fetching'

const app = combineReducers({
  isAppFetching,
  //other reducers
})

export default app

Wrap your App in the transition manager component

in your top level component, wrap it's contents with transition manger like so...

import TransitionManager from 'react-redux-transition-manager'

const ErrorPage = (props) => (
  <div className="Error">Ooops! there was an error...</div>
)

const LoadingIndicator = (props) => (
  <div className="Loader">loading...</div>
)

const App = (props) =>
  <TransitionManager {...props}
    onFetchStart={() => console.log('started fetching data for routes')}
    onFetchEnd={() => console.log('finished fetching data for routes')}
    onError={(err) => console.log('an error happened while fetching data for routes ', err)}
    FetchingIndicator={<LoadingIndicator />}
    ErrorIndicator={<ErrorPage />}
  >
    <Header />
    <div className="App">
      {props.children}
    </div>
  </TransitionManager>

this will do a few things. when the route starts to change, it will do the following:

  • call onFetchStart
  • render FetchingIndicator into the body of the page so you can style it above your app more easily and add a class to the body, TransitionManager-body-is-fetching
  • loop through the matched handlers looking for fetch methods.
  • call the fetch methods, collecting any promises.
  • wait for the promises to resolve before rendering the new route if promises are found. if none are found, it will resolve immediately.
  • on successful fetching, it will call onFetchEnd
  • on an error, it will call onError and render the ErrorIndicator component

you can connect other components to the store to see if it is fetching as well:

import { getFetching } from 'react-redux-transition-manager/redux/is-app-fetching'

//your component code...etc.
const mapStateToProps = (state, ownProps) => {
  return {
    isAppFetching: getFetching(state)
  }
}

Specifying route data needs

This allows you to specify at the route handler level what data that route needs via a static fetch method. The fetching itself should be wired up to redux via thunks, or whatever way you want to handle that. the only requirement is that the static method returns a promise.

import React, { Component } from 'react'
import { connect } from 'react-redux'
import fetchStuff from 'data/stuff/fetchStuff' //your async action

class Page extends Component {

  static fetch(params, query, { dispatch, getState }) {
    return dispatch(fetchAddresses())
  }

  render() {
    return (
      <p>{this.props.stuff}</p>
    )
  }
}

const mapStateToProps = (state, ownProps) => {
  return {
    stuff: state.stuff  
  }
}

export default connect(
  mapStateToProps
)(Page)

Static method params

The reactRouterFetch module is used to call the static methods on the matched route handlers. it will call the fetch method with the react router params(path params), the query(?id=whatever), and the redux dispatch and getState methods.

Props

onFetchStart: PropTypes.func - This is a function that will be called when fetching starts.

onFetchEnd: PropTypes.func - This is called when fetching ends

onError: PropTypes.func - This is called when an error occurs during transition, like a request fails

FetchingIndicator: PropTypes.element - This will be rendered outside the react component tree into the body, so you can use css to put it above the application.

ErrorIndicator: PropTypes.element - This will be rendered instead of props.children when an error occurs.

SplashScreen: PropTypes.element - This is the element to be shown for the initial page load. your loading indicator may be enough, so this is optional

fetchInitial: PropTypes.bool - This is for using this in client side apps only, this will initiate a fetch of the route right away, since the data wasn't loaded from the server.

showIndicatorOnInitial - This prop will control whether or not you want to also show your loading indicator on the initial load. Depending on your ui, you may want to have a splash screen with a loading bar at the top of the page or something.

Still to do:

  • add more tests for the actual component. sorry the coverage badge is so bad, i'm still learning enzyme. all the reducers are 100% covered
  • if your API returns an error that you want to handle more specifically, you need to do it in your error Indicator and access your redux store. While this is serviceable, I want to provided a pass-through, where if an error happens on a certain route, you will be able to handle the error in the route handler instead if you want to.