Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React - Invariant Violation: Minified React error #130. ONLY in Production

Using React Materialize's TextInput component breaks my site only in production.

In development it works fine. with no errors or warnings.

I've seen some Stack posts about components not being exported/imported correctly. However my components all appear to be exported/imported correctly. The TextFieldGroup component is a default export and is imported as such, while TextInput is a named export and is imported using curly brackets.

The TextFieldGroup is a wrapper component the handles all the input validation and renders the Materialize TextInput comp.

I have narrowed the issue down to the TextInput component as I have tried replacing the TextFieldGroup component with just the <input /> and putting the <input /> inside my TextFieldGroup wrapper comp.

Please my project with the issue. Click the login button to see if fail to render the page because its trying to the TextInput.

Login.js

import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import { Row, Col, Button } from 'react-materialize';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import TextFieldGroup from '../../components/common/TextFieldGroup';
import { loginUser } from '../../actions/authActions';

class Login extends Component {
    state = {
        usernameOrEmail: '',
        password: '',
        errors: {}
    }
    onChange = e => {
        const errors = this.state.errors;
        errors[e.target.name] = '';
        this.setState({
            [e.target.name]: e.target.value,
            errors
        });
    }
    onSubmit = e => {
        e.preventDefault();

        const userData = {
            usernameOrEmail: this.state.usernameOrEmail,
            password: this.state.password
        }
        this.props.loginUser(userData);
    }
    componentDidMount = () => {
        if (this.props.auth.isAuthenticated) {
            this.props.history.push('/dashboard');
        }
    }
    componentWillReceiveProps = (nextProps) => {
        if (nextProps.auth.isAuthenticated) {
            this.props.history.push('/dashboard');
        }
        if (nextProps.errors) {
            this.setState({errors: nextProps.errors});
        }
    }
    render() {
        const { errors } = this.state;

        return (
            <Row>
                <Col s={12} m={6} className="offset-m3">
                    <h2 className="center">Login</h2>
                    <form noValidate onSubmit={this.onSubmit}>
                        <Row>
                            <TextFieldGroup
                                placeholder="Username or email"
                                name="usernameOrEmail"
                                type="text"
                                value={this.state.usernameOrEmail}
                                onChange={this.onChange}
                                error={errors.usernameOrEmail}
                            />
                            <TextFieldGroup
                                placeholder="Password"
                                name="password"
                                type="password"
                                value={this.state.password}
                                onChange={this.onChange}
                                error={errors.password}
                            />
                            <Col s={12}>
                                <Link className='col s12' to="/forgotten-password">Forgotten password?</Link>
                                <Button className="btn-small right" waves="light">Login</Button>
                            </Col>
                        </Row>
                    </form>
                </Col>
            </Row>
        )
    }
}

Login.propTypes = {
    loginUser: PropTypes.func.isRequired,
    auth: PropTypes.object.isRequired,
    errors: PropTypes.object.isRequired
};

const mapStateToProps = (state) => ({
    auth: state.auth,
    errors: state.errors
});

export default connect(mapStateToProps, { loginUser })(Login);


TextFieldGroup.js

import React from 'react';
import classnames from 'classnames';
import propTypes from 'prop-types';
import { TextInput } from 'react-materialize';

const TextFieldGroup = ({
    name,
    placeholder,
    value,
    label,
    error,
    info,
    type,
    onChange,
    disabled
}) => {
    return (
        <React.Fragment>
            <TextInput
                type={type} 
                inputClassName={classnames('form-control form-control-lg', {
                    'is-invalid': error
                })}
                placeholder={placeholder}
                label={label}
                name={name} 
                s={12}
                value={value} 
                onChange={onChange}
                disabled={disabled}
            />
            {error && (<p className="red-text col s12 no-margin">{error}</p>)}
            {info && (<p className="helper-text col s12">{info}</p>)}
        </React.Fragment>
    )
}

TextFieldGroup.propTypes = {
    name: propTypes.string.isRequired,
    placeholder: propTypes.string,
    value: propTypes.string.isRequired,
    info: propTypes.string,
    error: propTypes.string,
    type: propTypes.string.isRequired,
    onChange: propTypes.func.isRequired,
    disabled: propTypes.string
}

TextFieldGroup.defaultProps = {
    type: 'text'
}

export default TextFieldGroup;

I expect the page to be able to render the login and register page correctly when using the React-Materialize TextInput component.

like image 254
daniel blythe Avatar asked Nov 07 '22 15:11

daniel blythe


1 Answers

Turns out I needed to delete package-lock.json and node_modules on the server then run $ npm install again.

like image 124
daniel blythe Avatar answered Nov 14 '22 22:11

daniel blythe