Skip to content

higher-order react component that manages data fetching with redux

License

Notifications You must be signed in to change notification settings

dlindenkreuz/redux-withdata

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

redux-withdata

higher-order react component that manages data fetching with redux

A central place to decide what data needs to be fetched for a component and what not.
Does not render the main component before everything is loaded.

npm version

This is WIP and needs tests and more detailed examples. Already seems to do fine in production, though 😁

Installation

requires react >= 0.14. You also need to install react-redux@4.x if you haven’t already.

$ npm i -S redux-withdata

Usage

Just use redux like you would usually do. Define conditions for dispatching actions in the withData HOC’s mapStateToRequests callback. Use compose from redux together with connect from react-redux.

Make sure that connect is the last argument of compose. The connect()ed component is rendered as soon as all data has loaded. You can safely assume that your mapStateToProps function works on a populated store state. Optionally, you may pass a LoadingComponent that is displayed in the meanwhile.

import { compose } from "redux"
import { connect } from "react-redux"
import withData from "redux-withdata"

class TodoApp extends React.Component {
  // …
}

function mapDispatchToProps(dispatch) {
  return {
    actions: bindActionCreators(actions, dispatch)
  }
}

function mapStateToRequests(stateProps, dispatchProps, ownProps) {
  // store state -> action creator callbacks
  // returned keys are arbitrary and passed to LoadingComponent as an array (example will follow)
  // only values that are callbacks will be executed
  // if no callbacks are left we assume that loading has finished and render the original component
  
  // roll your own conditions below
  // in this example, the reducer should set `loaded` to true upon successful fetching
  return {
    // do not execute the action creator here, just pass it as a callback
    // this expression is false if `loaded` is false.
    todos: !stateProps.todos.loaded && dispatchProps.actions.requestTodos
  }
}

function mapStateToProps(state) {
  // our "original" component is the `connect()`ed component
  // it won't be rendered and this won't get called until the data has loaded and all conditions have met
  // state.todos.byId has already been populated and we can do some transforms
  return {
    todos: _.mapValues(state.todos.byId, v => /* ... */)
  }
}

// no need to `mapDispatchToProps` twice, connect(TodoApp) is passed these props
compose(withData(mapDispatchToProps, mapStateToRequests), connect(mapStateToProps))(TodoApp)

API

withData(mapDispatchToProps, mapStateToRequests, [LoadingComponent])

Arguments

mapDispatchToProps(dispatch, [ownProps]) (object or function)

Internally, this is passed directly to connect and works just the same. Check out the react-redux api for more details.

mapStateToRequests(stateProps, dispatchProps, ownProps) (function)

This function is similar to mergeProps. You may use data from the store (stateProps), action props that you defined in mapDispatchToProps (dispatchProps) and props passed directly to the HOC (ownProps). This is the place to define conditions for actions to be executed in order to satisfy those same conditions after the store has been updated accordingly.

Return an object with arbitrary keys and values. All values that are callbacks are assumed to be action creators that are already bound to dispatch, other values are ignored. If that object does not contain any callbacks anymore, the original component is rendered and loading is finished.

[LoadingComponent] (react component)

If optionally passed, this component will be used to create a „loading“ view. All currently loading keys are passed to the component in an array through a loading prop. You may use this prop to display a detailed loading status. This component is unmounted as soon as the loading array is empty.

About

higher-order react component that manages data fetching with redux

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published