Search code examples
react-reduxredux-formredux-thunkreact-router-redux

Redux Form - I get an error when rendering the below custom component? Do not know why?


I am trying to render the following custom field component using redux-form, i am also passing custom props to the field component, however it keeps giving me an error as below:

invariant.js:42 Uncaught Error: Objects are not valid as a React child (found: object with keys {renderValidation}). If you meant to render a collection of children, use an array instead. in InputField (created by ConnectedField) in ConnectedField (created by Connect(ConnectedField)) in Connect(ConnectedField) (created by Field) in Field (created by LoginForm) in div (created by LoginForm) in form (created by LoginForm) in LoginForm (created by Form(LoginForm)) in Form(LoginForm) (created by Connect(Form(LoginForm))) in Connect(Form(LoginForm)) (created by ReduxForm) in ReduxForm (created by Login) in div (created by Login) in div (created by Login) in div (created by Login) in div (created by Login) in div (created by Login) in section (created by Login) in Login (created by Connect(Login)) in Connect(Login) (created by Route) in Route in div in Router (created by ConnectedRouter) in ConnectedRouter in Provider at invariant (invariant.js:42) at throwOnInvalidObjectType (react-dom.development.js:6748) at reconcileChildFibers (react-dom.development.js:7659) at reconcileChildrenAtExpirationTime (react-dom.development.js:7756) at reconcileChildren (react-dom.development.js:7747) at finishClassComponent (react-dom.development.js:7881) at updateClassComponent (react-dom.development.js:7850) at beginWork (react-dom.development.js:8225) at performUnitOfWork (react-dom.development.js:10224) at workLoop (react-dom.development.js:10288)

VM250629:20 The above error occurred in the component: in InputField (created by ConnectedField) in ConnectedField (created by Connect(ConnectedField)) in Connect(ConnectedField) (created by Field) in Field (created by LoginForm) in div (created by LoginForm) in form (created by LoginForm) in LoginForm (created by Form(LoginForm)) in Form(LoginForm) (created by Connect(Form(LoginForm))) in Connect(Form(LoginForm)) (created by ReduxForm) in ReduxForm (created by Login) in div (created by Login) in div (created by Login) in div (created by Login) in div (created by Login) in div (created by Login) in section (created by Login) in Login (created by Connect(Login)) in Connect(Login) (created by Route) in Route in div in Router (created by ConnectedRouter) in ConnectedRouter in Provider

Consider adding an error boundary to your tree to customize error handling behavior.

import React, { Component } from 'react';
import PropTypes from 'prop-types';

class InputField extends Component {
    render() {
        const { input, label, id, minlength, maxlength, required, meta: { touched, error } } = this.props;

        console.log('InputField - render', input, label, id, minlength, maxlength, required, touched, error);

        let renderValidation = function() {
            if (touched && !error) {
                return <i className="fa fa-check tm-form-valid"></i>;
            } else if (touched && error) {
                return <i className="fa fa-exclamation-triangle tm-form-invalid tooltip tooltip-effect tooltip-item"><span className="tooltip-content clearfix"><span className="tooltip-text">{error}</span></span></i>;
            }
        }

        return (
            <span className="input input--isao">
                <input {...input}
                    className="input__field input__field--isao"
                    spellCheck="false"
                    label={label}
                    id={id}
                    minLength={minlength}
                    maxLength={maxlength}
                    required={required} />
            </span>,

            <label className="input__label input__label--isao"
                htmlFor={id}
                data-content={label}>
                <span className="input__label-content input__label-content--isao">
                    {label}
                </span>
            </label>,

            {renderValidation}
        );
    }
}

InputField.propTypes = {
    input: PropTypes.object.isRequired,
    label: PropTypes.string.isRequired,
    id: PropTypes.string.isRequired,
    minlength: PropTypes.string.isRequired,
    maxlength: PropTypes.string.isRequired,
    required: PropTypes.bool.isRequired,
    meta: PropTypes.object.isRequired,
    touched: PropTypes.bool,
    error: PropTypes.string
};

export default InputField;


Solution

  • import React, { Component } from 'react';
    import PropTypes from 'prop-types';
    
    class InputField extends Component {
        render() {
            const { input, label, id, minlength, maxlength, required, meta: { touched, error } } = this.props;
    
            console.log('InputField - render', input, label, id, minlength, maxlength, required, touched, error);
    
            let renderValidation = function() {
                if (touched && !error) {
                    return <i className="fa fa-check tm-form-valid"></i>;
                } else if (touched && error) {
                    return <i className="fa fa-exclamation-triangle tm-form-invalid tooltip tooltip-effect tooltip-item"><span className="tooltip-content clearfix"><span className="tooltip-text">{error}</span></span></i>;
                }
            }
    
            return (<div className="wrapper">
                <span className="input input--isao">
                    <input {...input}
                        className="input__field input__field--isao"
                        spellCheck="false"
                        label={label}
                        id={id}
                        minLength={minlength}
                        maxLength={maxlength}
                        required={required} />
                </span>,
    
                <label className="input__label input__label--isao"
                    htmlFor={id}
                    data-content={label}>
                    <span className="input__label-content input__label-content--isao">
                        {label}
                    </span>
                </label>,
    
                {renderValidation}
            </div>);
        }
    }
    
    InputField.propTypes = {
        input: PropTypes.object.isRequired,
        label: PropTypes.string.isRequired,
        id: PropTypes.string.isRequired,
        minlength: PropTypes.string.isRequired,
        maxlength: PropTypes.string.isRequired,
        required: PropTypes.bool.isRequired,
        meta: PropTypes.object.isRequired,
        touched: PropTypes.bool,
        error: PropTypes.string
    };
    
    export default InputField;
    

    As mentioned above, render() can return only one element.