首页 > 解决方案 > React - 不变违规:缩小 React 错误 #130。仅在生产中

问题描述

使用 React Materialize 的TextInput组件只会在生产环境中破坏我的网站。

在开发中它工作正常。没有错误或警告。

我看过一些关于未正确导出/导入组件的 Stack 帖子。但是,我的组件似乎都已正确导出/导入。TextFieldGroup 组件是默认导出并按原样导入,而 TextInput 是命名导出并使用大括号导入。

TextFieldGroup 是一个包装器组件,它处理所有输入验证并呈现 Materialize TextInput 组件。

我已将问题缩小到 TextInput 组件,因为我尝试将 TextFieldGroup 组件仅替换为<input />并将其<input />放入我的 TextFieldGroup 包装器组件中。

请解决我的项目问题。单击登录按钮以查看是否无法呈现页面,因为它正在尝试使用 TextInput。

登录.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;

我希望页面能够在使用 React-Materialize TextInput 组件时正确呈现登录和注册页面。

标签: javascriptreactjswebpackmaterialize

解决方案


原来我需要删除服务器上的 package-lock.json 和 node_modules 然后$ npm install再次运行。


推荐阅读