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

Vue3 ( fix ) implement reactive args + fix many vue app creation issue #20712

Merged
merged 23 commits into from
Jan 23, 2023

Conversation

chakAs3
Copy link
Contributor

@chakAs3 chakAs3 commented Jan 20, 2023

Fixes #15567 fixes #13913

issue is not noticed but there is a risk of memory leak and performance issue as the vue component are growing and reactivity is complex

What I did

use reactive args and update them inside of re-creating the whole component and story again and again when the user is interacting

How to test

  1. Run a sandbox for template, e.g. yarn task --task sandbox --start-from auto --template vue3-vite/default-ts
  2. Open Storybook in your browser
  3. Use Vue devTools to inspect the reactivity and the number of Vue apps created each you navigate the Tree

image

Checklist

  • Make sure your changes are tested (stories and/or unit, integration, or end-to-end tests) yes
  • Make sure to add/update documentation regarding your changes
  • If you are deprecating/removing a feature, make sure to update
    MIGRATION.MD

Maintainers

  • If this PR should be tested against many or all sandboxes,
    make sure to add the ci:merged or ci:daily GH label to it.
  • Make sure this PR contains one of the labels below.

["cleanup", "BREAKING CHANGE", "feature request", "bug", "documentation", "maintenance", "dependencies", "other"]

Copy link
Contributor

@JReinhold JReinhold left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code looks clean! I haven't had a time to try it out yet, I'll do that next week.

Could you add a story that ensures the reactivity works? We can do that by having a stateful story that tests that changing args keeps the state.

So something like a button that increments a counter, and a play function that:

  1. resets args (so the play function can be run again and again)
  2. clicks button to increment counter
  3. asserts counter is incremented
  4. changes args by emitting an event
  5. asserts that args have changed, eg. the label on the button has changed
  6. asserts that the counter is still incremented - thus the state is still there and the component didn't remount.

All the necessary pieces for the above can be seen in this play function, but I'm happy to be more specific if you need me to.

If you add the story to code/renderers/vue3/template/stories it will be picked up by CI.

code/renderers/vue3/src/render.ts Outdated Show resolved Hide resolved
Copy link
Contributor Author

chakAs3 commented Jan 20, 2023

Yeah good idea let me try that I will come back to you @JReinhold if I have some questions

@chakAs3 chakAs3 changed the title Vue3 ( improvement ) implement reactive args + fix many vue app creation issue Vue3 ( fix ) implement reactive args + fix many vue app creation issue Jan 21, 2023
@chakAs3 chakAs3 requested a review from JReinhold January 22, 2023 23:10
@chakAs3
Copy link
Contributor Author

chakAs3 commented Jan 22, 2023

Hi, @JReinhold Let's start the week I hope you had a great weekend. I have done what you asked I think it needs some approval on chromatic since there are some new UIs, can you review it and let me know if it is OK for you?

Copy link
Contributor

@JReinhold JReinhold left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

great improvements! I have a few suggestions though.

code/renderers/vue3/src/render.ts Show resolved Hide resolved
code/renderers/vue3/src/render.ts Show resolved Hide resolved
@chakAs3 chakAs3 requested a review from JReinhold January 23, 2023 13:33
@JReinhold JReinhold assigned JReinhold and unassigned JReinhold Jan 23, 2023
Copy link
Contributor

@JReinhold JReinhold left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fantastic! 💪

@JReinhold JReinhold merged commit f62fb57 into storybookjs:next Jan 23, 2023
Comment on lines +12 to +19
// this is the story should be remove it will always fail, because forceReRender Api is removed in V7
export const ForceReRender = {
play: async ({ canvasElement }: PlayFunctionContext<any>) => {
const channel = globalThis.__STORYBOOK_ADDONS_CHANNEL__;
const button = await within(canvasElement).findByRole('button');
await button.focus();
await expect(button).toHaveFocus();

// forceRender is not called in V7
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually this test was a 🤦 . It should be emitting FORCE_REMOUNT. But the bigger issue is making sure it actual fails (chromatic & the test runner) when the assertion fails like this.

Copy link
Contributor Author

@chakAs3 chakAs3 Jan 24, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, I got it. let chromatic be happy.

@iamandrewluca
Copy link
Contributor

iamandrewluca commented Mar 27, 2023

When passing some component through args, and that component is rendered using <component/> a warning will be in the console. Maybe instead of using reactive, better to use the shallowReactive version or maybe even better shallowRef 🤔

vue received a component which was made a reactive object

@chakAs3
Copy link
Contributor Author

chakAs3 commented Mar 28, 2023

When passing some component through args, and that component is rendered using <component/> a warning will be in the console. Maybe instead of using reactive, better to use the shallowReactive version or maybe even better shallowRef 🤔

vue received a component which was made a reactive object

Oh yeah, passing a component as prop may cause some issues, as it should be serializable i hope it is a simple functional component, You are right in using shallowReactive to be safe, but we had some issues in case of altering the args with nested object that should be reactive in this case, anyway i will give it another try and see what we can do here to avoid this

Thanks for the advice

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