Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The view is not re-rendered on toolbar change #13791

Closed
ivayloc opened this issue Feb 2, 2021 · 17 comments
Closed

The view is not re-rendered on toolbar change #13791

ivayloc opened this issue Feb 2, 2021 · 17 comments

Comments

@ivayloc
Copy link

ivayloc commented Feb 2, 2021

Describe the bug
I have created a new toolbar button following the steps in the documentation, the button is for localization change, the problem is that the story won't re-render on globals change.

Expected behavior
I expect the page reloads as language is changed as it is in your official storybook

I am using @ngx-translate/core for managing the translations.

export const globalTypes = {
  locale: {
    name: 'Locale',
    description: 'Internationalization locale',
    defaultValue: 'en',
    toolbar: {
      icon: 'globe',
      items: [
        { value: 'en', right: 'en', title: 'English' },
        { value: 'he', right: 'he', title: 'Hebrew' },
      ],
    },
  },
};
const withLocaleProvider = (storyFunc, { globals: { locale } }) => {
  const story = storyFunc();

  story.moduleMetadata.imports.push(
    TranslateModule.forRoot({
      defaultLanguage: locale,
      useDefaultLang: true,
      loader: {
        provide: TranslateLoader,
        useFactory: HttpLoaderFactory,
        deps: [HttpClient],
      },
    })
  );
  return story;
}

export const decorators = [
  withLocaleProvider,
];

System

  System:
    OS: Windows 10 10.0.19041
    CPU: (8) x64 Intel(R) Core(TM) i5-8265U CPU @ 1.60GHz 
  Binaries:
    Node: 12.18.3 - C:\Program Files\nodejs\node.EXE      
    npm: 6.14.6 - C:\Program Files\nodejs\npm.CMD
  Browsers:
    Chrome: 87.0.4280.141
    Edge: Spartan (44.19041.423.0), Chromium (88.0.705.56)
  npmPackages:
    @storybook/addon-actions: ^6.1.15 => 6.1.15 
    @storybook/addon-essentials: ^6.1.15 => 6.1.15        
    @storybook/addon-links: ^6.1.15 => 6.1.15 
    @storybook/angular: ^6.1.15 => 6.1.15 
@ThibaudAV
Copy link
Contributor

ThibaudAV commented Feb 10, 2021

It is because of this forceRender
which precisely allows not to reload the component if only args change

but then it causes this kind of problem. I don't really know how to overcome this without specific configuration 🤷‍♂️

an untested idea:
You can directly call the forceReRender() function inside decorator. (import { forceReRender } from '@storybook/angular';)
but ⚠️⚠️ of infinite loop if you don't make a condition to call it only if value changes (it seems to me)

@ivayloc
Copy link
Author

ivayloc commented Feb 18, 2021

@ThibaudAV I tried the untested idea but nothing happened, the component didn't reload.

@bodograumann
Copy link
Contributor

I noticed the same thing with vue. In the docs tab auto-reload works though.

@gomorizsolt
Copy link

Same here, the "Docs" tab re-renders the component upon modifying the "globals" but the "Canvas" tab doesn't react to it.

@shilman
Copy link
Member

shilman commented Apr 14, 2021

Yay!! I just released https://github.com/storybookjs/storybook/releases/tag/v6.3.0-alpha.7 containing PR #14226 that references this issue. Upgrade today to the @next NPM tag to try it out!

npx sb upgrade --prerelease

Closing this issue. Please re-open if you think there's still more to do.

@shilman shilman closed this as completed Apr 14, 2021
@fabis94
Copy link

fabis94 commented Aug 26, 2021

The issue is still present, at least with Vue. The Vue component defined in the decorators array doesn't receive the updated globals value until a re-render happens some other way like when switching to a different story or the Docs tab.

@william-will-angi
Copy link

+1 Issue still in Vue latest version of Storybook 6.3.8. Solution for now is to include deprecated addon-contexts package for this functionality. Not the most ideal.

@sarayourfriend
Copy link

Solution for now is to include deprecated addon-contexts package for this functionality

@william-will-angi Can you elaborate on this workaround for Vue and how to implement it in the meantime until this is fixed?

@william-will-angi
Copy link

@sarayourfriend We were using @storybook/addon-contexts@5.3.21 with our Storybook 6.x app to provide our global values without any issues. their docs

If you're determined to make it work with addon-toolbar (which is the 6.x recommendation), I created a hacky workaround in this thread which manipulates the storybook canvas to force it to work.

@sarayourfriend
Copy link

I saw that. I was actually able to get it working using a Vue.observable and a watch in setup:

https://github.com/WordPress/openverse-frontend/pull/346/files#diff-8371d29d475d4942ba34da809defa80e7b18f01a65da98f700b7e103980f95eeR8

Thanks for the details though!

@wes0310
Copy link

wes0310 commented Oct 22, 2021

I also have encountered this problem but with React Project, any workaround to solve this problem? other than including the addon-context

@sarayourfriend
Copy link

@wes0310 For React you should be able to follow the pattern used by WordPress/Gutenberg here: https://github.com/WordPress/gutenberg/pull/35711/files#diff-493c10b62f2ed6d7c2a9945a55b58043b0f042c6b840f78c2193f8a01b2af613R15

Basically useEffect to watch the global variable, manipulate whatever context you need to, then call forceReRender(). (forceReRender does nothing for Vue but appears to work fine for React)

@wes0310
Copy link

wes0310 commented Oct 27, 2021

@wes0310 For React you should be able to follow the pattern used by WordPress/Gutenberg here: https://github.com/WordPress/gutenberg/pull/35711/files#diff-493c10b62f2ed6d7c2a9945a55b58043b0f042c6b840f78c2193f8a01b2af613R15

Basically useEffect to watch the global variable, manipulate whatever context you need to, then call forceReRender(). (forceReRender does nothing for Vue but appears to work fine for React)

I tried using forceReRender(), but appears to be useless.

@wes0310
Copy link

wes0310 commented Nov 5, 2021

Anyone who is keeping up with this problem?

@fabis94
Copy link

fabis94 commented Nov 5, 2021

I moved to using useChannel() to emit the updated value of the toolbar component instead, since the toolbar controls are rendered with React: https://storybook.js.org/docs/react/addons/addons-api#usechannel

And then I've created a Vue decorator that listens for this event and re-renders the story accordingly:

import { addons } from '@storybook/addons';

(story, ctx) => ({
    template: `<template v-if="cssType"><story /></template><template v-else><whatever/></template>`,
    created() {
      this.cssTypeUpdateListener = addons
        .getChannel()
        .addListener(EVENT_CSS_TYPE_UPDATED, ({ cssType: newVal }) => {
          this.cssType = newVal;
        });
    },
    destroyed() {
      addons
        .getChannel()
        .removeListener(EVENT_CSS_TYPE_UPDATED, this.cssTypeUpdateListener);
    },
})

@sarayourfriend
Copy link

@wes0310 it's a closed issue, I don't know much about this repository but maybe opening a new issue tagged for React with a reproduction repo would get more attention from the devs.

@william-will-angi
Copy link

This issue is open: #12840

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants