Search code examples
reactjsreact-contextstorybook

React Context and Storybook: Changing value of a React Context inside a component story


I'm wondering how I would go about changing the value of a React Context inside a component story in Storybook. I imagine there is a way to control this via the Story Controls, but there isn't any documentation on it.

I used this part of the Storybook documentation to provide my Stories with two seperate Contexts.

My code in .storybook/preview.js looks like this:

export const decorators = [
  (Story) => (
    <FilterProvider>
      <SearchQueryProvider>
        <Story />
      </SearchQueryProvider>
    </FilterProvider>
  ),
];

The FilterProvider and SearchQueryProvider code looks like this:

const SearchQueryProvider = ({ children }: SearchQueryProviderProps) => {
  const [searchQuery, setSearchQuery] = useState<string>("");

  return (
    <SearchQueryContext.Provider value={[searchQuery, setSearchQuery]}>
      {children}
    </SearchQueryContext.Provider>
  );
};

export { SearchQueryProvider, useSearchQuery };

The initial values of these states are basically empty. To test and preview my components which consume these Contexts I would now like to change the values inside Storybook.

If anyone has an idea how I could achieve this: I'd be delighted to know and grateful for you sharing your knowledge :)


Solution

  • You can add initialValue as property and set the initial value of the searchQuery state and use "" as default:

    const SearchQueryProvider = ({ children, initialValue = "" }: SearchQueryProviderProps) => {
      const [searchQuery, setSearchQuery] = useState<string>(initialValue);
    
      return (
        <SearchQueryContext.Provider value={[searchQuery, setSearchQuery]}>
          {children}
        </SearchQueryContext.Provider>
      );
    };
    
    export { SearchQueryProvider, useSearchQuery };
    

    This allows you to use your Provider like this:

    export const decorators = [
      (Story) => (
        <FilterProvider>
          <SearchQueryProvider initialValue="something">
            <Story />
          </SearchQueryProvider>
        </FilterProvider>
      ),
    ];