SCFi
SCFi

Reputation: 522

Warning when passing a function to a wrapped component prop

At present I have a ValidatedTextField component that wraps a TextField component and takes in a validationerror property that is used to communicate between the child and parent and consumed by either the onChange or onBlur event of the textbox.

However when passing a function to this attribute I receive the following error:

Invalid value for prop validationerror on tag. Either remove it from the element, or pass a string or number value to keep it in the DOM. For details, see https://reactjs.org/blog/2017/09/08/dom-attributes-in-react-16.html#changes-in-detail

I have read through the link which says that data and aria attributes can still be passed freely, however switching to using data attribute results in the same error. I cannot think how else to send the function to update the parents error back.

From the wrapper

<ValidatedTextField
    type="text"
    variant="standard"
    required={true}
    validateon={'onChange'}
    validate={[Validations.Required, Validations.allowedNameCharacters]}
    validationerror={(validationError: boolean) => this.setState({ HasError: validationError }) }
    onChange={(event: any) => this.setState({ textboxvalue: event.target.value })}
    value={this.state.textboxvalue}
/>

and the wrapped component

import * as React from 'react';
import * as _ from 'lodash'
import { IValidationItem } from '../../../Interfaces/IValidationItem'
import TextField, { TextFieldProps } from "@material-ui/core/TextField";

interface IValidatedTextFieldProps {
    validate?: IValidationItem[],
    validateon?: 'onBlur' | 'onChange',
    validationerror?: (hasError?: boolean) => void
}

interface IValidatedTextFieldState {
    validationErrorMessage: string,
    validationError: boolean
}


type ValidatedTextFieldAllProps = IValidatedTextFieldProps & TextFieldProps

class ValidatedTextField extends React.Component<ValidatedTextFieldAllProps, IValidatedTextFieldState> {

    public constructor(props: ValidatedTextFieldAllProps) {
        super(props);
        this.state = {
            validationErrorMessage: "",
            validationError: false
        }
    }
    public validationWrapper = (event: any) => {

        const { validate, } = this.props;
        return !validate ? "" : _.forEach(validate, (validationItem: IValidationItem) => {
            const result = !validationItem.func(event.target.value)

            if (result) {
                this.setState({ validationErrorMessage: validationItem.validationMessage });
                this.setState({ validationError: result })
                this.callParentValidationErrorMethod(result)
                return false;
            }
            else {
                this.setState({ validationErrorMessage: "" });
                this.setState({ validationError: result })
                this.callParentValidationErrorMethod(result)
                return;
            }
        });
    };

    public onBlurValidation = (event: any) => {
        const { onBlur, validateon, validate } = this.props;
        if (_.isFunction(onBlur)) { onBlur(event); }
        if (validateon === "onBlur" && !!validate) { this.validationWrapper(event); 
    }

    public onChangeValidation = (event: any) => {
        const { onChange, validateon, validate } = this.props;
        if (_.isFunction(onChange)) { onChange(event); }
        if (validateon === "onChange" && !!validate) { this.validationWrapper(event); };
    }
    public callParentValidationErrorMethod = (hasError: boolean) => {
        if(_.isFunction(this.props.validationerror)) {
            this.props.validationerror(hasError);
        }
    }

    public render() {
        const { validationErrorMessage, validationError } = this.state


        return (<TextField
            {...this.props}
            onBlur={(event: any) => { this.onBlurValidation(event); }}
            onChange={(event: any) => { this.onChangeValidation(event); }
            }
            error={validationError}
            helperText={validationErrorMessage}
        />)
    }
}

export default ValidatedTextField;

Additional info: Not seen in IE only chrome so far and currently React v16.6

Upvotes: 3

Views: 2482

Answers (1)

SCFi
SCFi

Reputation: 522

Alright Solved

Issue was that I was spreading all properties on the textfield in the component including the non existent attributes on the textfield. Extrapolating the properties I did not need and only binding the default text field properties fixed this issue

const {validationerror,validate,validateon, ...textFieldProps   } = this.props;
       return (<TextField
           {...textFieldProps}
           onBlur={(event: any) => { this.onBlurValidation(event); }}
           onChange={(event: any) => { this.onChangeValidation(event); }
           }
           error={validationError}
           helperText={validationErrorMessage}
       />)

Upvotes: 4

Related Questions