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

1

8

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 :)

Southeaster answered 19/7, 2021 at 13:32 Comment(0)
H
4

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>
  ),
];
Hargrove answered 22/7, 2021 at 8:54 Comment(2)
That works as far as I can set the value and it shows in the story. But I can't set this value in the Controls panel of a component story.Southeaster
If you set the initial value of your provider, I don't think that you can change it in the control panel. But you could do this to control the value (sorry, the format is messed up): jsx const Template = ({ searchQuery, ...args }) => ( <SearchQueryContext.Provider value={[searchQuery]}> <SearchComponent {...args} /> </SearchQueryProvider> ); export const WithProvider= Template.bind({}); WithProvider.args = { searchQuery: "", otherProperty: "with some value" }; If you use the control panel, the SearchComponent won't be able to change the value anymore.Hargrove

© 2022 - 2024 — McMap. All rights reserved.