【问题标题】:How to update components props in storybook如何更新故事书中的组件道具
【发布时间】:2018-02-05 16:26:33
【问题描述】:

我正在使用storybook (this) 单独使用我的组件。我想模拟所有通量周期(在完整的应用程序中,它是在 redux 的帮助下完成的)并使用故事中的一个简单对象更新属性,但我错过了一些东西。

  storiesOf('Color picker', module).add('base', () => {
    let colorPickerState = {
      changeColor: function(data) {
        this.color = data.color
      },
      color: '#00aced'
    }
    return (
      <ColorPicker
        name="color"
        onChange={colorPickerState.changeColor.bind(colorPickerState)}
        value={colorPickerState.color}
      />
    )
  }

我希望在调用onChange 时更新&lt;ColorPicker /&gt;value 属性;我可以看到colorPickerState.color 的值被正确更新,但组件没有重新渲染。

我错过了什么?

【问题讨论】:

    标签: javascript reactjs storybook


    【解决方案1】:

    在最新版本 (v6) 中,此功能调用 Args。 您还可以使用 argTypes 来查看操作的日志或指定道具。

    【讨论】:

      【解决方案2】:

      我会尝试使用 react 中的 useState 挂钩 - 通过其设置器更新状态值似乎具有重新渲染故事书组件的效果。

      我有一个类似的问题,我的数据输入表单的状态和事件处理(包括复杂的验证)是在全局范围内完成的,在组件树的上一级。通过编写一个简单的事件处理程序传递给我的组件,我能够获得该组件的工作演示及其复杂的验证。

      请注意,我的代码在 Typescript 中。我对 React 世界很陌生,所以这可能并不完美。

      // Things defined elsewhere: IComponentProps, IValidationResult, IFormInput, EntryForm
      // useState and useCallbac comes from react
      export const MyComponentDemo = (args: IComponentProps) => {
      
          const [validations, setValidations] = useState<IValidationResult[]>([]);
          const [theForm, setTheForm] = useState<IFormInput>(
              {
                  ...args.formValues,
                  // set other interesting default form values here
              }
          );
      
          const dummyValidationMethod = useCallback((form: IFormInput) => {
      
              let validations : IValidationResult[] = [];
      
              // Do validation using data from form
      
              setValidations(validations);
              setTheForm(form);
      
          }, []);
      
          return (
              <EntryForm
                  {...args}
                  formValues={theForm}
                  onValidation={dummyValidationMethod}
                  validatedLocations={validations}
              />
          );
      };
      

      【讨论】:

        【解决方案3】:

        您可以编写一个 dummy-component 来在其中呈现真实的 story 组件,然后您就可以拥有该 dummy-componentstate 属性。

        在下面的示例中,我在 Slider 组件的 story 中使用了knobs addon

        stories.addDecorator(withKnobs)
            .add('Slider', () => {
                // create dummy component that wraps the Slider and allows state:
                class StoryComp extends React.Component {
                    constructor( props ){
                        super(props);
        
                        this.state = {
                            value : this.props.value || 0,
                        }
                    }
        
                    onValueChange = value => this.setState({ value })
        
                    render(){
                        const props = {
                            ...this.props, 
                            onValueChange:this.onValueChange, // <--- Reason "StoryComp" is needed
                            value:this.state.value            // <--- Reason "StoryComp" is needed
                        }
        
                        return <Slider {...props} />
                    }
                }
        
                // knobs (customaziable props)
                const widthKnobOptions = {
                    range : true,
                    min   : 200,
                    max   : 1500,
                    step  : 1
                }
        
                const props = {
                    value : number('value', 200000),
                    min   : number('min', 100),
                    step  : number('step', 1000),
                    max   : number('max', 1000000),
                    width : number('width', 700, widthKnobOptions)
                }
        
                return <StoryComp {...props} />
            }
        );
        

        【讨论】:

        • 从哪里导入“storybookWrapper”?
        • @huseyin39 - 我的错误,我应该删除它,因为它只与我的实现相关(当时)[answer updated]
        【解决方案4】:

        您可以使用插件来实现此目的:https://github.com/Sambego/storybook-state

        所以你的代码看起来像:

        import { State, Store } from '@sambego/storybook-state';
        
        const store = new Store({
          value: '#00aced',
        });
        
        storiesOf('Color picker', module).add('base', () => {
          return (
            <State store={store}>
              <ColorPicker
                name="color"
                onChange={(data) => store.set({ value: data.color })}
              />
            </State>
          )
        }
        

        【讨论】:

        • 不使用第三方包怎么样?
        • ColorPicker 如何使用来自Statestore? (不清楚)
        • @vsync 通过将 store={store} 传递给 State
        • 我可能错了,但我认为@vsync 是在问如何在 ColorPicker 组件中使用存储在商店中的value?即使他们没有问这个问题,我也很想知道答案?
        猜你喜欢
        • 2020-09-15
        • 2018-04-15
        • 2022-01-21
        • 2020-02-25
        • 2019-12-17
        • 1970-01-01
        • 1970-01-01
        • 2020-10-29
        • 2022-01-20
        相关资源
        最近更新 更多