asyncBlurFields 在 Redux-Form 中不起作用
Posted
技术标签:
【中文标题】asyncBlurFields 在 Redux-Form 中不起作用【英文标题】:asyncBlurFields not working in Redux-Form 【发布时间】:2017-01-14 06:39:13 【问题描述】:我在使用 redux 形式的 asyncBlurFields 时遇到了一些问题,它只是没有响应,
容器:
import React, Component, PropTypes from 'react'
import connect from 'react-redux'
import SupplierEditForm from '../../components/suppliers/SupplierEditForm'
import reduxForm, change from 'redux-form'
import createSupplierRequest, updateSupplierRequest, fetchSupplierInfoRequest, validateSupplierRequest from '../../api/suppliers'
import resetSupplierForm, supplierFormSubmitSuccess from '../../actions/SuppliersActions'
class SuppliersEditView extends Component
constructor(props, context)
super(props, context);
this.state = isSubmitting: false
componentWillMount()
this.props.dispatch(resetSupplierForm())
componentDidMount()
if(this.props.params.supplier_id)
this.props.dispatch(fetchSupplierInfoRequest(this.props.params.supplier_id))
componentWillReceiveProps(nextProps)
if(nextProps.supplier.isAction==true)
if(!this.props.params.supplier_id)
this.context.router.push('/suppliers/edit/'+nextProps.supplier.supplier_id)
else
this.props.dispatch(fetchSupplierInfoRequest(nextProps.supplier.supplier_id))
this.setState(isSubmitting:true)
setTimeout(() =>
this.hideStatus()
this.props.dispatch(supplierFormSubmitSuccess())
, 1500)
hideStatus()
this.setState(isSubmitting:false)
render()
let pageHeader
if(this.props.fields.company_name.value)
pageHeader = <h1 className="page-header">Suppliers - this.props.fields.company_name.value </h1>
else
pageHeader = <h1 className="page-header">Suppliers</h1>
return (
<div className="container-fluid">
pageHeader
<SupplierEditForm
fields=this.props.fields
handleSubmit=this.props.handleSubmit
dispatchSupplier=this.props.dispatchSupplier.bind(this)
supplier=this.props.supplier.payload
isSubmitting=this.state.isSubmitting
dispatchFieldChange=this.props.dispatchFieldChange
supplier_id=this.props.params.supplier_id
/>
</div>
)
const validateSupplier = (values, dispatch) =>
console.log('hi')
return new Promise((resolve, reject) =>
dispatch(validateSupplierRequest(values))
.then((response) =>
console.log(response)
);
)
const mapStateToProps = (state) => (
supplier: state.suppliers.supplierInfo,
initialValues: state.suppliers.supplierInfo.payload
)
const mapDispatchToProps = (dispatch, props) => (
dispatchSupplier: (values) =>
!props.params.supplier_id ? dispatch(createSupplierRequest(values)) : dispatch(updateSupplierRequest(values, props.params.supplier_id))
,
dispatchFieldChange: (field, value) =>
dispatch(change('SupplierEditForm',field,value))
)
SuppliersEditView.propTypes =
asyncValidating: PropTypes.string.isRequired,
fields: PropTypes.object.isRequired,
resetForm: PropTypes.func.isRequired,
handleSubmit: PropTypes.func.isRequired,
submitting: PropTypes.bool.isRequired
SuppliersEditView.contextTypes =
router: PropTypes.object
SuppliersEditView = reduxForm(
form: 'SupplierEditForm',
fields: ['company_logo','company_name', 'business_registration_no', 'mailing_address', 'billing_address', 'phone', 'email', 'fax', 'contact_person', 'contact_phone', 'contact_email', 'comments'],
asyncValidate: validateSupplier,
asyncBlurFields:['business_registration_no']
)(SuppliersEditView)
export default connect(mapStateToProps, mapDispatchToProps)(SuppliersEditView)
组件:
import React, Component from 'react'
import Link from 'react-router'
import ReactDOM, findDOMNode from 'react-dom';
import config from '../../config'
import _ from 'lodash'
class SupplierEditForm extends Component
constructor(props, context)
super(props, context)
this.state =
file: null,
imagePreviewUrl: null
handleImageChange(e)
e.preventDefault();
let reader = new FileReader();
let file = e.target.files[0];
reader.onloadend = () =>
this.setState(
file: file,
imagePreviewUrl: reader.result
)
this.props.dispatchFieldChange(['company_logo'],file)
reader.readAsDataURL(file)
triggerImageUpload()
ReactDOM.findDOMNode(this.refs.upload).click()
render ()
const fields: company_logo, company_name, business_registration_no, mailing_address, billing_address, phone, email, fax, contact_person, contact_phone, contact_email, comments , handleSubmit, isSubmitting = this.props
let imageSection
if(this.state.imagePreviewUrl)
imageSection = <img src=this.state.imagePreviewUrl onClick=this.triggerImageUpload.bind(this)/>
else if (_.isEmpty(this.props.supplier) || _.isNull(this.props.supplier.filename))
imageSection = <div className="img-placeholder" onClick=this.triggerImageUpload.bind(this)></div>
else if (!_.isNull(this.props.supplier.filename) || !_.isEmpty(this.props.supplier))
imageSection = <img src=config.FILE_DIR + this.props.supplier.filename onClick=this.triggerImageUpload.bind(this)/>
return (
<form onSubmit=handleSubmit(this.props.dispatchSupplier) >
<button type="submit" disabled=isSubmitting className="btn btn-primary mr8">
isSubmitting == true ?
<i className="fa fa-circle-o-notch fa-spin fa-fw"></i>
:
'Save'
</button>
<Link to="/suppliers" className="btn btn-secondary">Back</Link>
<div className="row">
isSubmitting ?
<div className="form-overlay"/>
: null
<div className="col-md-6">
<h2 className="mb24">Supplier details</h2>
<div className="form-group">
<label>Company logo</label>
<div className="col-md-12">
imageSection
</div>
<input type="file" ref="upload" className="col-xs-12 mb24 hide" ...company_logo value=null onChange=this.handleImageChange.bind(this) />
</div>
<div className="form-group">
<label>Company name</label>
<input type="text" className="col-xs-12" ...company_name required/>
</div>
<div className="form-group">
<label>Business registration no.</label>
<input type="text" className="col-xs-12" ...business_registration_no required/>
</div>
<div className="form-group">
<label>Mailing address</label>
<input type="text" className="col-xs-12" ...mailing_address required/>
</div>
<div className="form-group">
<label>Billing address</label>
<input type="text" className="col-xs-12" ...billing_address required/>
</div>
<div className="form-group">
<label>Comments</label>
<textarea type="text" className="col-xs-12" ...comments required></textarea>
</div>
</div>
<div className="col-md-6">
<h2 className="mb24">Contact details</h2>
<div className="form-group">
<label>Phone</label>
<input type="text" className="col-xs-12" ...phone required/>
</div>
<div className="form-group">
<label>Fax</label>
<input type="text" className="col-xs-12" ...fax required/>
</div>
<div className="form-group">
<label>Email</label>
<input type="email" className="col-xs-12" ...email required/>
</div>
<div className="form-group">
<label>Contact person</label>
<input type="text" className="col-xs-12" ...contact_person required/>
</div>
<div className="form-group">
<label>Contact phone</label>
<input type="text" className="col-xs-12" ...contact_phone required/>
</div>
<div className="form-group">
<label>Contact email</label>
<input type="email" className="col-xs-12" ...contact_email required/>
</div>
</div>
</div>
</form>
)
export default SupplierEditForm
但是,每当提交表单时,business_registration_no 都应该响应输入失去焦点,但它没有响应,已经尝试了一整天。奇怪的是,在调用 handleSubmit 时,它并没有触发 this.props.dispatchSupplier,而是触发了 asyncValidate。我的代码有什么问题吗?急需帮助!!
【问题讨论】:
相信你需要使用redux表单的Field
组件,而不是html默认的input
s。来自文档 - <Field name="firstName" component="input" type="text"/>
(文档示例 - redux-form.com/6.0.2/docs/GettingStarted.md)
【参考方案1】:
是的。需要使用Field
-组件,然后还将onBlur
传递给该组件。
像这样:
https://github.com/erikras/redux-form/issues/1834 左右:
render()
const input: value, onChange, onBlur , meta: touched, error = this.props
return (
<div>
<div className="example-class">
<input
type="tel"
className=this.inputFormClass(touched, error)
autoComplete="on"
onChange=this.setPhoneNumber.bind(this)
placeholder="some Placeholder"
onBlur=() => onBlur(value)
/>
</div>
this.showErrorMessage(touched, error)
</div>
)
【讨论】:
以上是关于asyncBlurFields 在 Redux-Form 中不起作用的主要内容,如果未能解决你的问题,请参考以下文章
NOIP 2015 & SDOI 2016 Round1 & CTSC 2016 & SDOI2016 Round2游记