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

Changes to global values do not cause re-render of docs templates in 6.5 #18477

Closed
micahgodbolt opened this issue Jun 14, 2022 · 20 comments
Closed

Comments

@micahgodbolt
Copy link
Contributor

Describe the bug
In 6.4 a change to a global value would cause docs page template to re-render with the new context, allowing UI to update in the page template. In 6.5 global value updates are only reflected in stories, not in the docs page templates themselves.

To Reproduce

I've created a reduced test case repro at https://github.com/micahgodbolt/storybook-context-test
Repo is currently in 6.4. Test to see expected functionality, then change to 6.5 and see the regression.

System
System:
OS: Windows 10 10.0.22621
CPU: (12) x64 Intel(R) Core(TM) i7-8700K CPU @ 3.70GHz
Binaries:
Node: 16.15.0 - C:\Program Files\nodejs\node.EXE
Yarn: 1.22.0 - C:\Program Files (x86)\Yarn\bin\yarn.CMD
npm: 8.5.5 - C:\Program Files\nodejs\npm.CMD
Browsers:
Edge: Spartan (44.22621.1.0)
npmPackages:
@storybook/addon-actions: 6.5.9 =>6.5.9
@storybook/addon-essentials: 6.5.9 => 6.5.9
@storybook/addon-interactions: 6.5.9 => 6.5.9
@storybook/addon-links: 6.5.9 => 6.5.9
@storybook/builder-webpack4: 6.5.9 => 6.5.9
@storybook/manager-webpack4: 6.5.9 => 6.5.9
@storybook/react: 6.5.9 => 6.5.9
@storybook/testing-library: ^0.0.13 => 0.0.13

@tmeasday
Copy link
Member

OK. This was an intentional change, but I can see that there are globals (e.g. theme) that you would want to re-render the template when they change. Is that correct?

@micahgodbolt do you agree that the template should NOT re-render when individual story args change?

@micahgodbolt
Copy link
Contributor Author

yeah, i'm only concerned with globals, which by definition can be consumed anywhere in the application.

Go to https://react.fluentui.dev/?path=/docs/components-accordion--default

Click on the "Theme" dropdown in the upper right. And then select Teams Dark. Note that the story re-renders with the new dark theme, but the dropdown value does not update. The dropdown is being rendered in the page template. Note that the new dropdown value updates correctly as soon as I change component page.

theme
.

@shilman
Copy link
Member

shilman commented Jul 25, 2022

Yo-ho-ho!! I just released https://github.com/storybookjs/storybook/releases/tag/v7.0.0-alpha.16 containing PR #18711 that references this issue. Upgrade today to the @future 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 Jul 25, 2022
@shilman
Copy link
Member

shilman commented Jul 26, 2022

Whoopee!! I just released https://github.com/storybookjs/storybook/releases/tag/v6.5.10-alpha.0 containing PR #18711 that references this issue. Upgrade today to the @prerelease NPM tag to try it out!

npx sb upgrade --prerelease

@micahgodbolt
Copy link
Contributor Author

I've tried this out and it doesn't appear to work yet. I've updated my test repo to make the steps a bit clearer to follow, as well as updated it to your latest alpha version

https://github.com/micahgodbolt/storybook-context-test

@tmeasday
Copy link
Member

Ah! Ok, that's because you are reading context.globals which is a deprecated field and will be removed in 7.0.

I guess the correct way to access them in a container would be:

  const story = context.storyById(context.id);
  const { globals } = context.getStoryContext(story);

@tmeasday
Copy link
Member

(Note in 7.0 context.id will be removed and you'd change the first line to context.storyById()-- but that doesn't work in 6.5 🤔 )

@tmeasday
Copy link
Member

PS there is a small bug in the test repo in that it updates the value but then emits the previous value. Not a big deal but you just have to click the button twice to see it actually work.

@micahgodbolt
Copy link
Contributor Author

micahgodbolt commented Aug 1, 2022

@tmeasday is there no way to create a global context anymore?

We're using addons.getChannel().emit('updateGlobals', {globals: {values}})

We want to write a control that lives in the page template, that can switch the current app theme globally. This worked in 6.4, but does not work any longer.

I tried your suggestion, but that context is only the component context which does not include that global value

@tmeasday
Copy link
Member

tmeasday commented Aug 2, 2022

@micahgodbolt I think maybe I'm misunderstanding. Here's the code I tried, which worked as I understood the problem: https://github.com/micahgodbolt/storybook-context-test/pull/1/files

@shilman
Copy link
Member

shilman commented Aug 4, 2022

Shiver me timbers!! I just released https://github.com/storybookjs/storybook/releases/tag/v6.5.10 containing PR #18711 that references this issue. Upgrade today to the @latest NPM tag to try it out!

npx sb upgrade

@jakewtaylor
Copy link

I'm pretty sure I'm still seeing this in 6.5.15, using storybook builder vite, maybe that has something to do with it? Anyone else still seeing this issue?

@menssen
Copy link

menssen commented Feb 26, 2023

Ah! Ok, that's because you are reading context.globals which is a deprecated field and will be removed in 7.0.

I guess the correct way to access them in a container would be:

  const story = context.storyById(context.id);
  const { globals } = context.getStoryContext(story);

@tmeasday In 7.0, is there a way to access globals from a raw doc page that is not associated with a story (or, more specifically, from a DocsContainer)? Previously context.globals worked on the DocsContext that's passed to DocsContainer, but since it no longer exists, and context.storyById() throws an error if on a page not tied to a story, there is no obvious way to do this now.

@tmeasday
Copy link
Member

Hmm, I don't think it's an official API but you could access context.store.globals.globals

@tmeasday
Copy link
Member

@JReinhold we should consider an API for this.

@Driesigner
Copy link

I don't see this working. I'm using storybook 7.0.18. Here's my decorator:

const withI18next = (Story, context) => {
  const { locale } = context.globals;

  useEffect(() => {
    i18next.changeLanguage(locale);
  }, [locale]);

  return (
    <I18nextProvider
      i18n={i18next
        //.use(LanguageDetector)
        .use(initReactI18next)
        .init({
          //debug: true,
          supportedLngs: ['en', 'nl', 'fr', 'de'],
          interpolation: {
            escapeValue: true,
          },
        })
      }
    >
      <Story/>
    </I18nextProvider>
  );
};

export const globalTypes = {
  locale: {
    name: 'Locale',
    description: 'Internationalization locale',
    toolbar: {
      icon: 'globe',
      items: [
        { value: 'nl', title: 'Nederlands' },
        { value: 'fr', title: 'Français' },
        { value: 'de', title: 'Deutsch' },
        { value: 'en', title: 'English' },
      ],
      showName: true,
    },
  },
};

When changing the language, the story doesn't update. However, when I navigate to another story and then return, the value has been updated...

@tmeasday
Copy link
Member

tmeasday commented Jun 7, 2023

@Driesigner this seems like a different issue, what you're describing is a simple failure of a decorator to rerun when a global changes. That's a very core feature of SB so I'd be pretty surprised if it was broken.

What happens if you log inside the decorator? Does it rerun when the global changes?

@giorgiabosello
Copy link

giorgiabosello commented Jun 8, 2023

I don't see this working. I'm using storybook 7.0.18. Here's my decorator:

const withI18next = (Story, context) => {
  const { locale } = context.globals;

  useEffect(() => {
    i18next.changeLanguage(locale);
  }, [locale]);

  return (
    <I18nextProvider
      i18n={i18next
        //.use(LanguageDetector)
        .use(initReactI18next)
        .init({
          //debug: true,
          supportedLngs: ['en', 'nl', 'fr', 'de'],
          interpolation: {
            escapeValue: true,
          },
        })
      }
    >
      <Story/>
    </I18nextProvider>
  );
};

export const globalTypes = {
  locale: {
    name: 'Locale',
    description: 'Internationalization locale',
    toolbar: {
      icon: 'globe',
      items: [
        { value: 'nl', title: 'Nederlands' },
        { value: 'fr', title: 'Français' },
        { value: 'de', title: 'Deutsch' },
        { value: 'en', title: 'English' },
      ],
      showName: true,
    },
  },
};

When changing the language, the story doesn't update. However, when I navigate to another story and then return, the value has been updated...

I'm having the same issue!
I'm changing a global outside of a Story, so I do not have the context of the Story.

import { addons } from '@storybook/addons'
import { FORCE_RE_RENDER } from '@storybook/core-events'

useEffect(() => {
    addons.getChannel().emit(FORCE_RE_RENDER)
}, [globals.auth])

addons.getChannel().emit(FORCE_RE_RENDER) doesn't trigger a re-render of the Story, I can achieve what I want with a simple window.location.reload() inside the useEffect. I would prefer that the emit event would work though.

I'm using storybook 7.0.18

@tmeasday
Copy link
Member

addons.getChannel().emit(FORCE_RE_RENDER) doesn't trigger a re-render of the Story

Again, this is pretty surprising as it's a core feature of SB. It's difficult do say more without more information @giorgiabosello, I would suggest opening a new issue with a reproduction showing how the situation comes about.

@giorgiabosello
Copy link

addons.getChannel().emit(FORCE_RE_RENDER) doesn't trigger a re-render of the Story

Again, this is pretty surprising as it's a core feature of SB. It's difficult do say more without more information @giorgiabosello, I would suggest opening a new issue with a reproduction showing how the situation comes about.

In the end, I've used FORCE_REMOUNT, which is what is used on the toolbar button to remount the story, and I trigger it every time a global variable changes.

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

7 participants