You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React组件TS报错及导出输入组件值获取问题(Storybook设计系统)

Storybook搭建设计系统的两个问题解决方案

问题1:TypeScript错误:Type '{ children: string; }' has no properties in common with type 'IntrinsicAttributes'.ts(2559)

原因

LoginPage中使用<InputEmail> {}<InputEmail>时,给组件传递了空的children内容,但你的InputProps(以及基于它封装的InputEmail组件的Props)并没有定义children属性,TypeScript会严格校验组件接收的属性是否符合定义,因此抛出错误。另外这里的{}属于无效写法,完全没必要传递。

解决方法

直接移除InputEmail标签之间的{},修改为:

<InputEmail />

如果你的InputEmail确实需要支持children,需要在InputProps中添加对应属性:

export type InputProps = {
  type: 'email' | 'password',
  children?: React.ReactNode
}

问题2:无法在LoginPage中获取InputEmail的输入值

原因

当前的Input组件内部维护了独立的inputText状态,没有将输入值和变更逻辑暴露给父组件,导致LoginPage无法同步收集输入内容。

解决方法

将Input组件改为受控组件,由父组件控制输入值和变更回调:

  1. 修改InputProps,添加value和onChange属性:
import { ChangeEvent } from 'react';

export type InputProps = {
  type: 'email' | 'password',
  value: string,
  onChange: (e: ChangeEvent<HTMLInputElement>) => void
}
  1. 重构Input组件,移除内部状态,使用父组件传递的属性:
import React, { ChangeEvent } from 'react';

export type InputProps = {
  type: 'email' | 'password',
  value: string,
  onChange: (e: ChangeEvent<HTMLInputElement>) => void
}

export const Input: React.FC<InputProps> = ({ type, value, onChange }) => {
  const getPlaceholder = () => {
    return type === 'email' ? 'Email' : 'Password';
  }

  return (
    <main>
      <input 
        type={type}
        name={type}
        id={type}
        onChange={onChange}
        placeholder={getPlaceholder()}
        value={value}
        className="input-style"
      />
    </main>
  );
}
  1. 在LoginPage中,将状态传递给对应Input组件并绑定变更回调:
export const LoginPage: React.FC<LoginPageProps> = ({ }) => {
  const [email, setEmail] = React.useState("")
  const [password, setPassword] = React.useState("")

  const handleEmailChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    setEmail(e.target.value);
  }

  const handlePasswordChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    setPassword(e.target.value);
  }

  const show = () => {
    console.log('Email:', email, 'Password:', password);
  }

  return (
    <main className="container">
      <section className="logo">
        <Logo size="small" />
      </section>
      <section className="container-input">
        <div className="input-email">
          <InputEmail value={email} onChange={handleEmailChange} />
        </div>
        <div className="input-password">
          <InputPassword value={password} onChange={handlePasswordChange} />
        </div>
        <Button label="button" onClick={show} backgroundColor="white" />
      </section>
    </main>
  );
}

(注:假设InputEmail和InputPassword是基于Input的封装组件,可参考这个写法:export const InputEmail = (props: Omit<InputProps, 'type'>) => <Input type="email" {...props} />)


内容的提问来源于stack exchange,提问作者Samuel Máximo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 23:34:50