Search code examples
reactjsreduxreact-reduxstorybook

How do I write a storybook story for a component that has redux-connected component as grandchild?


We are building a Storybook UI library from our existing code base. The code wasn't written with component driven development in mind. There are many instances where a component renders descendants that are connected to the Redux store.

E.g., Parent (connected) -> Child (unconnected) -> Grandchild (connected)

Now if I'm building a story for Parent, I understand how to pass hard-coded data as a prop to an immediate child component in order to avoid Redux all together. However, I can't figure out how to do this when the connected component is more deeply nested.

Ideally I don't want to have to use Redux at all for stories, but even if I do initialize a Redux store and wrap the parent component in a Provider as described here, would this even work to connect the grandchild component?

Any ideas would be helpful.


Solution

  • When using storybook you can add a Decorator for all stories (see link for most updated API).

    It is common to wrap your stories with the state manager store provider in order to not break the story avoiding "adding a store for each story".

    // @ config.js
    import { configure,  addDecorator } from '@storybook/react';
    
    import React from 'react';
    import { createStore } from 'redux';
    import { Provider } from 'react-redux';
    import rootReducer from 'reducers/root.reducer';
    
    const store = createStore(rootReducer);
    
    addDecorator(S => (
      <Provider store={store}>
        <S />
      </Provider>
    ));
    
    
    configure(require.context('../src', true, /\.stories\.js$/), module);
    

    Note that you can avoid connecting all your components with redux-hooks which in addition removes all the boilerplate code of redux.

    React Redux now offers a set of hook APIs as an alternative to the existing connect() Higher Order Component. These APIs allow you to subscribe to the Redux store and dispatch actions, without having to wrap your components in connect().