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默认的inputs。来自文档 - &lt;Field name="firstName" component="input" type="text"/&gt;(文档示例 - 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游记

秋的潇洒在啥?在啥在啥?

上传的数据在云端的怎么查看,保存在啥位置?

在 React 应用程序中在哪里转换数据 - 在 Express 中还是在前端使用 React?

存储在 plist 中的数据在模拟器中有效,但在设备中无效

如何在保存在 Mongoose (ExpressJS) 之前在模型中格式化数据