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组件改为受控组件,由父组件控制输入值和变更回调:
- 修改
InputProps,添加value和onChange属性:
import { ChangeEvent } from 'react'; export type InputProps = { type: 'email' | 'password', value: string, onChange: (e: ChangeEvent<HTMLInputElement>) => void }
- 重构
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> ); }
- 在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
相关产品推荐
相关产品推荐

