skip to Main Content

I am using Storybook and React-Redux.

I have a global decorator in preview.js, which adds the store like so:

import { addDecorator } from '@storybook/react';
import ProviderWrapper from '../src/components/Provider'; //Provides the store

addDecorator(storyFn => <ProviderWrapper>{storyFn()}</ProviderWrapper>

The ProviderWrapper is just (more or less):

import { Provider } from 'react-redux';
import { configureStore } from '../redux/configureStore';

const store = configureStore();
export const ProviderWrapper = ({ children }) =>
    (<Provider store={store}>{children}</Provider>)

Configure store is currently very simple: const configureStore = () => createStore(reducers);

The issue I have is that when I try to use react-redux hooks in one of my components, and set it up I get this error message:

could not find react-redux context value; please ensure the component is wrapped in a <Provider>

My Component uses the store like so:

const MyLovelyComponent = () => {
   const { myData, lovelyData } = useSelector(selectMyLovelyData);
   return (
      <Paper>
        <MyComponent data={myData} />
        <LovelyComponent data={lovelyData} />
      </Paper>
   );
};

And when I use it in a story I have it set up in this way:

export default {
    title: 'MyLovelyComponent',
    Component: MyLovelyComponent
}

export const UsingRedux = () => {
    const dispatch = useDispatch();
    useEffect(() => {
      dispatch(updateMyData(myData)); // actionCreator for updating state
      dispatch(updateLovelyData(lovelyData));
    }, []);
    return (<MyLovelyComponent />);
}

It feels like everything should be set up to work, so I can’t figure out why I am getting that error.


If it helps,here os my dependency treefpr react/redux etc. This may be relevant based on this github issue:

[email protected] /home/centos/transformation-comparison
┠─┰ @storybook/[email protected]
│ ┠─┰ @storybook/[email protected]
│ │ └── [email protected]  deduped
│ ┠─┰ @storybook/[email protected]
│ │ └── [email protected]  deduped
│ └── [email protected]  deduped
┠─┰ @storybook/[email protected]
│ └─┰ @storybook/[email protected]
│   └─┰ @storybook/[email protected]
│     └── [email protected]  deduped
┠── [email protected] 
┠── [email protected] 
└── [email protected]

Again, no sure if it is relevant but on the off chance it helps I’ve included it.

2

Answers


  1. Chosen as BEST ANSWER

    I've resolved my issue by moving the code from the decorator into the story itself. Long term this is not ideal, obviously.

    export default {
        title: 'MyLovelyComponent',
        Component: MyLovelyComponent
    }
    
    const UsingReduxComponent = () => {
        const dispatch = useDispatch();
        useEffect(() => {
          dispatch(updateMyData(myData)); // actionCreator for updating state
          dispatch(updateLovelyData(lovelyData));
        }, []);
        return (<MyLovelyComponent />);
    }
    
    export const UsingRedux = () => (
        <ProviderWrapper>
            <UsingReduxComponent />
        </ProviderWrapper>
    )
    
    

  2. you have to pass store in both provider and wrapper also.

    import { Provider } from 'react-redux';
    import { configureStore } from '../redux/configureStore';
    
    const store = configureStore();
    
    const ProviderWrapper = ({ children, store }) => (
        <Provider store={store}>
            {children}
        </Provider>
    );
    
    export const withProvider = (story) => (
        <ProviderWrapper store={store}>
            {story()}
        </ProviderWrapper>
    )
    
    
    // in config.js file
    
    import { withProvider } from './Provider.js';
    addDecorator(withProvider);
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search