代码之家  ›  专栏  ›  技术社区  ›  sefirosu

React Typescript storybook使用onChange回调实现自定义的输入组件,然后将状态值设置回输入

  •  0
  • sefirosu  · 技术社区  · 5 年前

    我目前正在用storybook实现一个React定制的输入组件。 我希望实现的是这个定制的输入组件只需要几个参数,其中一个参数是 onChangeInput ,稍后将负责设置“input value”的状态值,下面是我的主要输入组件实现:

    import React from 'react'
    
    export type Props = {
      /**
       * This is the Label text value
       */
      labelText?: string,
      /**
       * Placeholder text for input
       */
      placeholder?: string,
      /**
       * Classes defined here will be appended to the input's default classes
       */
      className?: string,
      /**
       * Value attribute of Input
       */
      value?: string,
      /**
       * Name attribute of Input
       */
      name?: string,
      /**
       * Label for attribute
       */
      htmlFor?: string,
      /**
       * Callback for when user typing in Input
       */
      onChangeInput: any,
    }
    
    /**
     * Generic input component.
     */
    export function Input({labelText, placeholder='', className='', value='', name='', htmlFor='', onChangeInput}:Props) {    
        return (
            <div>
                <label className='text-text-01-normal font-medium text-sm leading-5' htmlFor={htmlFor}>
                    {labelText}
                </label>
                <div className="relative">
                    <input
                        id={htmlFor}
                        className={[
                            "relative w-64 pl-3 h-8 py-2 border rounded bg-ui-03 border-ui-06 text-text-01-normal leading-5 text-sm text-left hover:bg-ui-03 hover:border-ui-07 focus:bg-ui-03 focus:outline-none focus:border-interactive-01-active active:bg-ui-03",                        
                            className
                            ].join(' ')} 
                        placeholder={placeholder}
                        value={value}
                        name={name}
                        onChange={ (e) => { onChangeInput(e.target.value) }}
                    />
                </div>
            </div>
        )
    }   
    

    然后在我的故事书档案里,我希望有一个钩子 useState 对于 localValue ,何时 OnChange输入 作为传入自定义输入组件的方法,本地onChange from Input将开始让它设置localValue的状态,因此我的自定义输入组件可以在用户键入时显示输入值。。。

    输入.stories.tsx

    import React, { useState } from 'react';
    import { Story, Meta } from '@storybook/react';
    import { withDesign } from 'storybook-addon-designs'
    
    import { Input, Props } from './Input';
    
    const [localValue, setValue] = useState<string>('');
    const onChangeInput = (inputValue: string) => {
        console.log(inputValue);
        setValue(inputValue);
    }
    
    export default {
      title: 'General/Input',
      component: Input,
      decorators: [withDesign],
      parameters: {
        design: {
          type: 'figma',
        },
      },
    } as Meta;
    
    const Template: Story<Props> = (args:Props) => <Input {...args} />;
    
    export const Default: Story<Props> = Template.bind({});
    Default.args = {
      labelText: 'Label',
      placeholder: 'Placeholder',
      name: 'test-name',  
      htmlFor: 'test-for',
      value: localValue,
      onChange: onChangeInput,
    } as Partial<Props>;
    Default.parameters = {
      design: {
        url: 'https://www.figma.com/to-some-design-url'
      }
    }
    

    但不幸的是,我不能得到它的工作,所以在这里寻求帮助,请与代码示例建议,谢谢

    0 回复  |  直到 5 年前
        1
  •  3
  •   sefirosu    5 年前

    经过我自己的调查。这辆车没问题输入.tsx文件。 以下是解决方案,工作正常,对于以后搜索同一问题的任何人,请随时复制粘贴到您自己的项目:)

    import React, { useState } from 'react';
    import { Story, Meta } from '@storybook/react';
    import { withDesign } from 'storybook-addon-designs'
    
    import { Input, Props } from './Input';
    
    export default {
      title: 'General/Input',
      component: Input,
      decorators: [withDesign],
      parameters: {
        design: {
          type: 'figma',
        },
      },
    } as Meta;
    
    const Template: Story<Props> = () => {    
        const [localValue, setValue] = useState<string>('');
        const onChangeInput = (inputValue: string) => {
            setValue(inputValue);
        }
        return (
            <Input 
                labelText='Label'
                placeholder='Placeholder'
                className='test-class-name'
                name='test-name'            
                value={localValue}
                htmlFor='test-for'
                onChangeInput={ onChangeInput }
            />
        )
    }
    
    export const Default: Story<Props> = Template.bind({});
    Default.parameters = {
      design: {
        url: 'https://www.figma.com/link-to-design'
      }
    }