自定义门户组件内部包含Redux表单?

时间:2017-06-23 14:05:03

标签: reactjs redux redux-form

我在尝试将redux-form放入我创建的自定义模式组件中时遇到此错误:Error: Field must be inside a component decorated with reduxForm()

基本上,我有一个用户看到他们的帖子的视图。当转到编辑帖子的名称时,会弹出一个表单,使用模态组件显示redux表单。当用户单击模态上的“保存/提交”按钮时,我希望表单进行验证,然后回调到父帖子视图组件,后者将处理调用操作创建者以更新帖子名称。

我认为这与我尝试使用props.children将表单传递给我的模态有关。在尝试找到解决方案时,我发现了一些关于React.cloneElement的内容,但我不确定如何使用它,如果这甚至可以帮助我解决这个问题。也许我应该采取完全不同的方法?

通过模态表单:

// ----- IMPORTS ----- //
import React, { Component } from 'react';
import { Field, reduxForm } from 'redux-form';

import Modal from '../overlays/modal';
import { validate } from '../../validators/post-validator';


// ----- COMPONENT ----- //
class MyModal extends Component {

    constructor( props ) {

        super( props );
        this.onSubmit = this.onSubmit.bind( this );
    }

    render() {

        const { handleClose, handleSubmit, show } = this.props;

        return (
            <Modal handleClose={ handleClose } show={ show }>
                <form onSubmit={ handleSubmit( this.onSubmit ) }>
                    <Field
                        name="name"
                        type="text"
                        component="input"
                    />
                    <button type="button" onClick={ handleClose }>Cancel</button>
                    <button type="submit">Save</button>
                </form>
            </Modal>
        );
    }

    onSubmit( values ) {
        console.log( 'MyModal: onSubmit', values );

        e.preventDefault();
        this.props.handleConfirm( values );
    }
}


// ----- EXPORT ----- //
export default reduxForm( {
    form: 'editNameForm',
    validate
} )( MyModal );

模态:

// ----- IMPORTS ----- //
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';

import store from '../../stores/store';


// ----- COMPONENT ----- //
class Modal extends Component {

    constructor( props ) {

        super( props );

        this.modalContainer;
        this.modalWrapper;

        this.onClick = this.onClick.bind( this );
    }

    componentDidMount() {

        this.modalWrapper = document.createElement( 'div' );
        document.body.appendChild( this.modalWrapper );
        this.renderModal();
    }

    componentDidUpdate() {
        console.log( 'Modal: componentDidUpdate', this.props.show );

        this.renderModal();
    }

    componentWillUnmount() {

        document.body.removeChild( this.modalWrapper );
        this.modalWrapper = undefined;
    }

    render() {
        console.log( 'Modal: render', this.props.show );

        return <noscript />;
    }

    renderModal() {

        const modalClass = ( this.props.show ) ? 'modal fade in': 'modal fade';
        const modalDisplay = ( this.props.show ) ? 'block': '';
        const modalStyle = { display: modalDisplay };

        ReactDOM.render(
            <Provider store={ store }>
                <div className={ modalClass } tabIndex="-1" ref={ elem => { this.modalContainer = elem; } } role="dialog" style={ modalStyle } onClick={ this.onClick }>
                    <div className="modal-dialog" role="document">
                        <div className="modal-content">
                            { this.props.children }
                        </div>
                    </div>
                </div>
            </Provider>
        , this.modalWrapper );
    }

    onClick( e ) {
        console.log( 'Modal: onClick' );

        e.preventDefault();

        if ( !this.props.disabled && e.target === this.modalContainer )
            this.props.handleClose( e );
    }
}


// ----- EXPORT ----- //
export default Modal;

0 个答案:

没有答案