@react-frontend-developer/react-redux-render-prop

1.0.22 • Public • Published

react-redux-render-prop

This is a render-props version of react-redux.

To give credits to react-redux, take into account that react-redux is way more sophisticated. react-redux-render-prop does not guarantee the proper order of updates as is the case for react-redux. For smaller projects and where your global state is not too deep, react-redux-render-prop can still be considered as an alternative. To learn more about what this solution is missing comparing to react-redux please consult Implement React Redux from Scratch.

In the advent of react hooks and suspense and with official public context API, you may consider to stop using redux at all.

Installing

yarn add @react-frontend-developer/react-redux-render-prop

Usage

First on the top level of the project do:

import { WithStore } from '@react-frontend-developer/react-redux-render-prop'
import { store } from 'your-redux-store'
import { ConnectedComponent } from './ConnectedComponent'

const App = () => (
  <WithStore.Provider value={{store}}>
    <ConnectedComponent />
  </WithStore.Provider>
)

Then in ConnectedComponent (or any other component down the tree that needs to access Redux state) you do:

import React from 'react'
import { WithStore } from '@react-frontend-developer/react-redux-render-prop'
import { MyActions } from './actions'

class ConnectedComponent extends React.Component {
  onClick = dispatch => {
    dispatch(MyActions.actionCreator())
  }
  render () {
    return (
      <WithStore
        selector={state => ({
          prop1: state.prop1,
          prop2: state.prop2
        })} >
        { ({ prop1, prop2 }, dispatch) =>
          <div>
            <p>prop1 is {prop1}</p>
            <p>prop2 is {prop2}</p>
            <button onClick={() => this.onClick(dispatch)}>Dispatch</button>
          </div>
        }
      </WithStore>
    )
  }
}

export { ConnectedComponent }

If you like you can also use a render prop:

<WithStore
  selector={state => ({
    prop1: state.prop1,
    prop2: state.prop2
  })} 
  render={({ prop1, prop2 }, dispatch) =>
    <div>
      <p>prop1 is {prop1}</p>
      <p>prop2 is {prop2}</p>
      <button onClick={() => this.onClick(dispatch)}>Dispatch</button>
    </div>
  }
/>

You can use WithStore without providing a selector. This is useful when your component wants to be able to dispatch actions but is not per-se interested in observing the state:

<WithStore
  render={dispatch =>
    <div>
      <p>I do not care about the state!</p>
      <button onClick={() => this.onClick(dispatch)}>Dispatch</button>
    </div>
  }
/>

or

<WithStore>
  { dispatch =>
      <div>
        <p>I do not care about the state!</p>
        <button onClick={() => this.onClick(dispatch)}>Dispatch</button>
      </div>
  }
</WithStore>

For testing, we also provide a simple, ready to use mock that you can use as a manual mock. First on the top-level of your app (or where your NODE_PATH points to) create a folder @react-frontend-developer and inside it file react-redux-render-prop.js. Inside that file put:

import { WithStoreMock } from '@react-frontend-developer/react-redux-render-prop'

const WithStore = WithStoreMock

export { WithStore }

Then in your tests, you just do:

import React from 'react'
import ReactDOM from 'react-dom'
import renderer from 'react-test-renderer'
import { ConnectedComponent } from './ConnectedComponent'
import { WithStore } from '@react-frontend-developer/react-redux-render-prop'

const state = {
  prop1: 'test value for prop1',
  prop2: 'test value for prop1'
}

WithStore.mockStore(state)

it('renders without crashing', () => {
  const div = document.createElement('div')
  ReactDOM.render(<ConnectedComponent />, div)
})

it('renders correctly', () => {
  const component = renderer
    .create(<ConnectedComponent />)
  expect(component.toJSON()).toMatchSnapshot()
})

Package Sidebar

Install

npm i @react-frontend-developer/react-redux-render-prop

Weekly Downloads

0

Version

1.0.22

License

MIT

Unpacked Size

65.6 kB

Total Files

24

Last publish

Collaborators

  • everydayproductive
  • jeroenknoops
  • markspanbroek