Changing value of control does not re-render a component fully
See original GitHub issueTo Reproduce Steps to reproduce the behavior:
- Select ‘s’ in the ‘dialogModalSize’ control dropdown
- Click on the component’s button with the text ‘open modal’
Expected behavior The modal window to be the smallest width size.
Actual behavior The modal window is not changed in width size.
When changing to the ‘save-button’ component and then on ‘Dialog Modal > Default’ again the changes do apply.
Other controls such as ‘dialogTitle’ are indeed working. The difference with the ‘size’ control is that the ‘title’ text control is not set in the ngOnInit
lifecycle method.
So maybe changing a value in the control is not really creating a new instance of the component?
Screenshot
Code snippets
Contrived example, but it will show the gist:
export default {
title: 'Components/MyComponent',
component: MyComponent,
decorators: [...],
argTypes: {
size: { control: { type: 'select', options: ['xs', 's', 'm', 'l', 'xl'] } },
title: { control: { type: 'text' }
}
} as Meta;
const Template: Story<MyComponent> = (args) => ({
template: `
<my-component [title]="title" [size]="size">
</my-component>
`
});
MyComponent:
type Size = 'xs' | 's' | 'm' | 'l' | 'xl';
@Component({
selector: `my-component`,
templateUrl: './my.component.html,
})
export class MyComponent implements OnInit {
// ... left out for brevity
@Input()
title: string;
@Input()
size: Size;
ngOnInit(): void {
const width = this.size ? this.sizes[this.size].width : this.sizes[this.breakpoint].width;
this.config = Object.assign(
new MatDialogConfig(),
{ width, minHeight: '320px' }
);
}
}
System System: OS: macOS 10.15.7 CPU: (8) x64 Intel® Core™ i7-6700HQ CPU @ 2.60GHz Binaries: Node: 12.18.3 - ~/.nvm/versions/node/v12.18.3/bin/node Yarn: 1.22.4 - /usr/local/bin/yarn npm: 6.14.6 - ~/.nvm/versions/node/v12.18.3/bin/npm Browsers: Chrome: 87.0.4280.88 Firefox: 83.0 Safari: 14.0 npmPackages: @storybook/addon-actions: 6.1.0 => 6.1.0 @storybook/addon-essentials: 6.1.0 => 6.1.0 @storybook/addon-links: 6.1.0 => 6.1.0 @storybook/angular: 6.1.0 => 6.1.0
Issue Analytics
- State:
- Created 3 years ago
- Comments:7 (4 by maintainers)
Top GitHub Comments
I think that would have to be a new feature, because the controls are not supposed to completely rerender the story when changed. They instead update the inputs, like if you were changing the value of your inputs in an actual Angular app. I try to make sure my inputs are not limited to usage in
ngOnInit
, but of course there are cases that may be difficult to do that or require it to be that way.I think the button in the top right is supposed to reset the component, even though it doesn’t actually recreate the component last I checked.
I could see the usefulness of a button to reinitialize the component and, even though I would try to avoid it myself, I could see providing an option to reinitialize on control change as useful to some. Maybe a
parameter
option or individual control option. I could see this being a feature that isn’t limited to Angular and if the option already exists and I just missed it, then we can just fix it for Angular.@sanbornhilland That hack made me think of one that could be done for the Angular renderer. I don’t know enough about Storybook’s React renderer, but I assume your hack could be wrapped into a decorator, like the following, also.
This decorator could be used to force a full rerender each time props changes, because changes in
moduleMetadata
cause the story to be fully rerendered. I put a provider containing props, that I won’t be using, in themoduleMetadata
and if props is different then it will causemoduleMetadata
to be different. The decorator could be placed globally, per file, or per story.If you want a button to rerender, which should work for any framework, the following could be used to make an addon that adds a full rerender button to the toolbar.