React中通过事件函数向styled component传递布尔值的问题求解
解决方案
1. 先修正状态更新的错误写法
你当前直接修改SignInData状态的写法属于状态突变,React无法检测到状态变更,所以你才需要额外加Update状态强制刷新,属于不必要的冗余逻辑,先修改为标准的不可变更新:
const [SignInData, setSignInData] = useState({Username:'',Password:''} as StringKeyValue) const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => { setSignInData(prev => ({ ...prev, [e.target.name]: e.target.value })) }
修改后可以直接删除Update状态和对应的空useEffect。
2. 解决isFilled传值问题
你原来的写法逻辑不成立:isFilled需要接收布尔值,你传入的是函数,styled组件不会主动执行这个函数,且渲染阶段根本不存在事件对象e,所以不可能通过这种方式拿到输入框值。
最简直接方案
直接根据输入框的name属性,从状态中取对应值判断是否为空,直接传入布尔值即可:
<InputFields isFilled={SignInData.Username !== ''} type="text" name="Username" onBlur={handleChange} /> <InputFields isFilled={SignInData.Password !== ''} type="password" name="Password" onBlur={handleChange} />
高复用通用方案
如果表单字段很多,不想每个输入框都手写isFilled判断,可以选择以下两种方案任意一种:
- 方案1:封装通用表单输入组件,自动根据name判断是否为空
// 封装组件 const FormInput = ({ name, type, formData, handleChange, ...rest }: { name: keyof StringKeyValue, type: string, formData: StringKeyValue, handleChange: (e: React.ChangeEvent<HTMLInputElement>) => void }) => { return <InputFields isFilled={formData[name] !== ''} name={name} type={type} onBlur={handleChange} {...rest} /> } // 调用时无需再写isFilled逻辑 <FormInput formData={SignInData} handleChange={handleChange} type="text" name="Username" /> <FormInput formData={SignInData} handleChange={handleChange} type="password" name="Password" />
- 方案2:直接修改styled组件定义,内置判断逻辑
// styled组件定义时增加接收formData和name的声明 const InputFields = styled.input<{name: keyof StringKeyValue, formData: StringKeyValue}>` /* 原有样式 */ /* 可以直接在样式里根据name取状态判断,不需要单独传isFilled */ border-color: ${props => props.formData[props.name] ? '#165DFF' : '#DCDFE6'}; ` // 调用时直接传formData和name即可 <InputFields formData={SignInData} type="text" name="Username" onBlur={handleChange} />
内容的提问来源于stack exchange,提问作者MrBunny
相关产品推荐
相关产品推荐

