Redux Form如何从高阶组件(HOC)向Input元素传递Props?
拆解Redux Form + Native Base的表单代码疑惑
嘿,我来帮你把这段代码里的疑惑点一一掰明白,都是Redux Form的核心玩法,搞懂之后用起来就顺手多了~
1. input 对象到底是什么?
Redux Form的Field组件最核心的作用就是帮你把表单字段的状态(比如值、输入事件)和Redux Store绑定起来。它会自动生成一个包含所有表单控制逻辑的input对象,然后传给你自定义的渲染组件(也就是这里的renderInput)。
这个input里包含了所有你需要的表单控制属性,比如:
value: 当前字段的实际值(由Redux Store管理)onChange: 值改变时的回调函数(自动同步到Redux Store)onBlur: 字段失去焦点时的回调(用来触发校验)name: 字段的名称(和你在Field里写的name对应)
所以你写<Input {...input} />,本质就是把这些控制属性一次性传递给Native Base的Input组件,让它和Redux Form的状态系统联动起来——不用你自己手动维护state里的字段值,Redux Form全帮你搞定了。
2. 其余属性的来源
你在renderInput里解构的label、meta,还有你在Field上写的type、placeholder这些,来源分两类:
meta: Redux Form自动注入的元数据对象,专门用来做表单校验和状态提示,里面的touched(字段是否被点击/输入过)、error(校验错误信息)、warning(警告信息)都是Redux Form根据你的校验规则自动生成的。比如你代码里判断hasError,就是用meta.error来做错误提示的依据。label、type、placeholder等: 这些是你在Field组件上手动添加的属性,Redux Form会把这些额外属性原封不动地传递给renderInput函数。比如你写<Field name="email" ... placeholder="Username" />,placeholder就会作为参数传给renderInput,你可以直接解构出来用。
3. 如何添加自定义Props?
添加自定义Props超级简单,分两步:
- 在
Field组件上直接添加你需要的自定义属性,比如:
<Field name="email" component={this.renderInput} type="text" placeholder="Username" // 自定义属性 customColor="#ff0000" showIcon={true} />
- 在
renderInput函数里解构出这些自定义属性,然后按需使用:
renderInput({ input, label, meta: { touched, error, warning }, // 拿到自定义属性 customColor, showIcon }){ const hasError = error !== undefined; return( <Item error={hasError}> <Input {...input} style={{color: customColor}} /> {hasError ? <Text>{error}</Text> : null} {showIcon && <Icon name="mail" />} </Item> ) }
这样就能把自定义的属性传递给你的渲染组件,灵活扩展表单的功能。
附你提供的代码片段整理
renderInput函数
renderInput({ input, label, meta: { touched, error, warning } }){ console.log(input) var hasError= false; if(error !== undefined){ hasError= true; } return( <Item error= {hasError}> <Input {...input} /> {hasError ? <Text>{error}</Text> : <Text />} </Item> ) }
调用renderInput的render方法
render(){ const { handleSubmit, reset } = this.props; if (!this.state.isReady) { return <Expo.AppLoading />; } return ( <Container> <Header> <Body> <Title>Redux Form</Title> </Body> </Header> <Content padder> <Field name="email" component={this.renderInput} model="sudhakar" type="text" placeholder="Username" /> <Field name="name" component={this.renderInput} type="password" placeholder="Password" /> <Input name="age" type="text" ref="_age" /> <Button block primary onPress= {this.handleLogin} style={{marginHorizontal:10,backgroundColor:"#00adef", marginTop:50}} > <Text>Submit</Text> </Button> </Content> </Container> ) }
内容的提问来源于stack exchange,提问作者Sudhakar
相关产品推荐
相关产品推荐

