我在使用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} width="100" 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} width="100" 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。我的代码有什么问题吗?急需帮助!!
答案 0 :(得分:0)
是的。需要使用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>
)
}