首页 > 解决方案 > 我有这个错误-> Uncaught TypeError: _this.props.login is not a function

问题描述

朋友们好~我有一个问题~我目前正在做一个叫做Lead Manager的简单项目。但是现在有一个问题。登录按钮不读取 onSubmit 上的道具。目前,Chrome 出现以下错误。

错误部分:未捕获的类型错误:_this.props.login 不是函数 Login.js:74

src/components/accounts/Login.js

import React, { Component } from 'react'
import TextField from '@material-ui/core/TextField';
import Typography from '@material-ui/core/Typography';
import Box from '@material-ui/core/Box';
import Button from '@material-ui/core/Button';
import { Link, Redirect } from 'react-router-dom';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import { login } from '../../actions/auth';

export class Login extends Component {
    state = {
        username: '',
        password: ''
    }

    static propTypes = {
      login: PropTypes.func.isRequired,
      isAuthenticated: PropTypes.bool
    }

  onChangeName = (e) => this.setState({ username: e.target.value });
  onChangePW1 = (e) => this.setState({ password: e.target.value });

  onSubmit = e => {
    e.preventDefault();
    console.log(this.props.login) // undefined;
    this.props.login(this.state.username, this.state.password); <- error;
  }

  render() {
    if (this.props.isAuthenticated) {
      return <Redirect to='/' />;
    }
    const { username, password } = this.state;
    return(
      <Typography component="div" variant="body1">
         <Box color="success.main">
           <div>
             <h2>Login</h2>
             <form onSubmit={this.onSubmit}>
               <div className="form-group">
                 <TextField
                id="standard-multiline-flexible"
                label="UserName"
                type="text"
                required
                multiline
                inputProps={{ maxLength: 10 }}
                style={{
                  width: '70%',
                  marginLeft: '15%',
                  marginRight: '15%',             
                  paddingBottom: 10,
                  marginTop: 0,
                }}
                getvalue={username}
                onChange={this.onChangeName}
            />
          </div>
          <div className="form-group">
            <TextField
            id="standard-multiline-flexible"
            label="Password"
            type="text"
            required
            multiline
            inputProps={{ maxLength: 20 }}
            style={{
              width: '70%',
              marginLeft: '15%',
              marginRight: '15%',             
              paddingBottom: 10,
              marginTop: 0,
            }}
            getvalue={password}
            onChange={this.onChangePW1}
            />
          </div>
          <Button type='submit' color="primary" style={{marginLeft: '15%'}} >Login</Button>
              <p align="center">
              Don't hava an account? <Link to="/register">Register</Link>
              </p>
            </form>
          </div>
        </Box>
      </Typography>
    );
  }
}

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

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

src/actions/auth.js

import axios from 'axios';
import { returnErrors } from './messages';
import {
USER_LOADED,
USER_LOADING,
AUTH_ERROR,
LOGIN_SUCCESS,
LOGIN_FAIL
} from './types';

// CHECK TOKEN & LOAD USER
export const loadUser = () => (dispatch, getState) => {
// User Loading
dispatch({ type: USER_LOADING });

// Get token from state
const token = getState().auth.token;
console.log(token)
// Headers
const config = {
    headers: {
        'Content-Type': 'application/json'
    }
}

// If token, add to headers config
if(token) {
    config.headers['Authorization'] = `Token ${token}`;
}

axios.get('/api/auth/user', config)
.then(res => {
    dispatch({
        type: USER_LOADED,
        payload: res.data
    })
}).catch(err => {
    dispatch(returnErrors(err.response.data, err.response.status));
    dispatch({
        type: AUTH_ERROR
    })
})
}

// LOGIN USER
export const login = (username, password) => dispatch => {
// Headers
const config = {
    headers: {
        'Content-Type': 'application/json'
    }
}

// Request Body
const body = JSON.stringify({ username, password });
console.log(body)
axios.post('/api/auth/login', body, config)
.then(res => {
    dispatch({
        type: LOGIN_SUCCESS,
        payload: res.data
    })
}).catch(err => {
    dispatch(returnErrors(err.response.data, err.response.status));
    dispatch({
        type: LOGIN_FAIL
    })
})
}

src/components/App.js

import React, { Component, Fragment } from "react";
import ReactDom from "react-dom";
import { HashRouter as Router, Route, Switch, Redirect } from "react-router-dom";
import Header from "./layout/Header";
import Dashboard from "./leads/Dashboard";
import Alerts from './layout/Alerts';
import Register from './accounts/Register';
import { Login } from './accounts/Login';
import PrivateRoute from './common/PrivateRoute';
import { Provider as AlertProvider, positions } from 'react-alert';
import AlertMUITemplate from 'react-alert-template-mui';
import { Provider } from "react-redux";
import store from "../store";
import { loadUser, login } from '../actions/auth';

// Alert Options
 const alertOptions = {
  position: positions.MIDDLE
} 

class App extends Component {
  componentDidMount(){
    store.dispatch(loadUser())
  }

  render() {
     return (
  <Provider store={store}>
  <AlertProvider template={AlertMUITemplate}{...alertOptions}>
    <Router>
      <Fragment>
        <Header />
        <Alerts />
        <div className="container">
          <Switch>
            <PrivateRoute exact path="/" component={Dashboard} />
            <Route exact path="/register" component={Register} />
            <Route exact path="/login" component={Login} />
          </Switch>
        </div>
      </Fragment>
      </Router>
      </AlertProvider>
      </Provider>
    );
  }
 }

ReactDom.render(<App />, document.getElementById("app"));

如何解决它?...如果您能帮助我,我将不胜感激。

标签: javascriptreactjsreact-redux

解决方案


src/components/App.js 中更改以下内容:

import { Login } from './accounts/Login';

import Login from './accounts/Login';

该应用程序仍然以您最初导入它的方式呈现Login组件,因为您export class Login在 Login.js 文件中有。当您使用命名的 import{ Login }时,它正在导入未连接到 Redux 的此类,因此您将无法访问isAuthenticatedlogin道具。您实际上可以在export此处删除该单词。

要获取连接到 Redux 的类,您需要默认导出,即Login.


推荐阅读