Storybook: Ability to refresh (force rerender) of story

Created on 25 Aug 2017  路  11Comments  路  Source: storybookjs/storybook

It would be neat if addons could tell the Storybook API to refresh a given story. Using storybookAPI.selectStory() does nothing if the story is already selected.

This would be useful when a story wants to customize hot-reloading to maintain parts of its state, through e.g. a Redux store. This would support stories like this:

import { storiesOf } from '@storybook/react';
import reselectStory from 'storybook-hot';
import * as React from 'react';

import configureStore from './configureStore';
import HotStory from './HotStory';

// Configure your Redux store once. If you make edits to *this* module, it
// will get hot-reloaded by its parent so that your Redux state gets reset.
const store = configureStore();

// Store a mutable reference to the story, which gets replaced on hot reload
let Story = HotStory;

storiesOf('Hot story').add('Example', () => <Story store={store} />);

// Whenever the story changes, get the new module and tell Storybook to
// re-render us.
module.hot.accept('./HotStory', () => {
  Story = require('./HotStory').default;

  // Tell our addon to tell the API to reselect our story.
  reselectStory('Hot story', 'Example');
});

I've already written an addon (unpublished) which does this by selecting another (dummy) story and selecting back to the original story. It works, quite well, but requires a dummy story. This is obviously imperfect, and you still have to do hard reloads from time-to-time, but it comes close to the "regular" app workflow but I can isolate mocking my network stack to my stories, specifically.

The relevant "blocker" is in init_api.js#L48. I realize you wouldn't usually want to emit an event for the same story, but maybe there could be an escape hatch for an explicit re-render?

addons stories

All 11 comments

This is really interesting!
We actually do need a good method to push new data to a currentSelectedStory, because Vue and Angular work quite different from react. And we want to wrap the storyFn as little as possible actually.

1209

Hi everyone! Seems like there hasn't been much going on in this issue lately. If there are still questions, comments, or bugs, please feel free to continue the discussion. We do try to do some housekeeping every once in a while so inactive issues will get closed after 90 days. Thanks!

I'll take a crack at it when I get a chance

Released as 3.4.0-alpha.0

Is there any doc on how to use this/is this actually available?

awesome!
is this method available for the react native storybook?
I couldn't see it in the src

No. I'm going to support it there as part of #3555 (It's needed for knobs)

How do I use this in Angular? Any examples?

How do we use this with Ember? Is there support for that?

For anyone trying to accomplish this in combination with a button-knob, I managed to do so with a little workaround.

It's important that you specify a key that is based on a counter variable which you update. This key will be used by React to determine if it should re-render or not. I tried getting it to work in combination with the forceReRender function but that didn't work

_(input on how to get this working using the forceReRender method is very welcome as it didn't trigger a re-render for me)_

It's worth noting that a global variable should exist, f.e. _counter_ which you update. Not the most elegant, but it works.

import { button } from '@storybook/addon-knobs';

let counter = 0;
const reRender = () => ( counter += 1)

storiesOf("Story title", module).add("default", () => {
  button("Refresh story", reRender);
  return (
    <div key={counter}>Content of the story</div>
  )
});

I'm using @storybook/[email protected]

Was this page helpful?
0 / 5 - 0 ratings

Related issues

tirli picture tirli  路  3Comments

purplecones picture purplecones  路  3Comments

arunoda picture arunoda  路  3Comments

shilman picture shilman  路  3Comments

dnlsandiego picture dnlsandiego  路  3Comments