【问题标题】:action is not a function react-reduxaction 不是函数 react-redux
【发布时间】:2020-05-29 06:59:01
【问题描述】:

login undefined

在我创建 AppRoutes.js 并将一些路由移动到该文件之前,每当我单击登录按钮时,它都可以正常工作。

TypeError:登录不是函数

这是代码结构。

这是启动应用程序的主文件,登录路径被放置在 AppRoutes 组件中。

  1. app.js
import React, { Fragment, useEffect } from 'react'
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom'
import Navbar from './components/layout/Navbar'
import Landing from './components/layout/Landing'
import Alert from './components/layout/Alert'
import { loadUser } from './actions/auth'
import { Provider } from 'react-redux'
import setAuthToken from './utils/setAuthToken'
import store from './store'
import './App.css'
import AppRoutes from './components/routing/AppRoutes'
if (localStorage.token) {
  setAuthToken(localStorage.token)
}
const App = () => {
  useEffect(() => {
    store.dispatch(loadUser())
  }, [])
  return (
    <Provider store={store}>
      <Router >
        <Fragment>
          <Navbar />
          <Alert />
          <Switch>
            <Route exact path='/' component={Landing} />
            <Route component={AppRoutes} />
          </Switch>

        </Fragment>
      </Router>
    </Provider>
  )
}

export default App

2.AppRoutes.js

import React, { Fragment } from 'react'
import { Register } from '../auth/Register'
import { Login } from '../auth/Login'
import Dashboard from '../dashboard/Dashboard'
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom'
import PrivateRoute from './PrivateRoute'
import { NotFound } from '../layout/NotFound'
import store from '../../store'
import { Provider } from 'react-redux'
const AppRoutes = () => {
    return (<Fragment>
        <Switch>
            <Route exact path='/register' component={Register} />
            <Route exact path='/login' component={Login} />
            <PrivateRoute path='/dashboard' component={Dashboard} >
            </PrivateRoute>
            <Route component={NotFound} />
        </Switch>
    </Fragment>
    )
}

export default AppRoutes
  1. auth.js
export const login = (email, password) => async dispatch => {
    const config = {
        headers: {
            'Content-Type': 'application/json'
        }
    }

    const body = JSON.stringify({ email, password })
    try {
        const res = await axios.post('/api/auth', body, config)
        if (res?.data?.token) {
            dispatch({
                type: LOGIN_SUCCESS,
                payload: res.data
            })
            dispatch(loadUser())
        }
        else {
            dispatch(setAlert(res.data.msg, 'success'))
        }
    } catch (error) {
        const errors = error.response.data.errors
        if (errors) {
            errors.forEach(error => dispatch(setAlert(error.msg, 'danger')))
        }
        dispatch({
            type: LOGIN_FAIL
        })
    }
}

4.Login.js

import React, { Fragment, useState } from 'react'
import { connect } from 'react-redux'
import PropTypes from 'prop-types'
import { login } from '../../actions/auth'
import { Link, Redirect } from 'react-router-dom'
import store from '../../store'

export const Login = ({ isAuthenticated, login }) => {
    const [formData, setFormData] = useState({

        email: '',
        password: ''

    })

    const { email, password } = formData

    const onChange = e => setFormData({ ...formData, [e.target.name]: e.target.value })

    const onSubmit = e => {
        e.preventDefault()
        console.log(typeof login)
        login(email, password)
    }

    //redirect if logged in

    if (isAuthenticated) {
        return <Redirect to='/dashboard' />
    }

    return (
        <Fragment>
            <div className="m-5">
                <div className="row justify-content-center">
                    <div className="col-md-4">
                        <div className="card shadow-lg o-hidden border-0 my-5">
                            <div className="card-body p-0">
                                <div>
                                    <div className="p-5">
                                        <div className="text-center">
                                            <h4 className="text-dark mb-4">Welcome Back!</h4>
                                        </div>
                                        <form className="user" onSubmit={e => onSubmit(e)}>
                                            <div className="form-group">
                                                <input className="form-control form-control-user" type="email" placeholder="Email Address" name="email" value={email} onChange={e => onChange(e)} required />
                                            </div>
                                            <div className="form-group">
                                                <input className="form-control form-control-user" type="password"
                                                    placeholder="Password"
                                                    name="password"
                                                    minLength="6"
                                                    value={password} onChange={e => onChange(e)}
                                                />
                                            </div>
                                            <div className="form-group">
                                                <div className="custom-control custom-checkbox small">
                                                    <div className="form-check">
                                                        <input className="form-check-input custom-control-input" type="checkbox" id="formCheck-1" />
                                                        <label className="form-check-label custom-control-label" htmlFor="formCheck-1">Remember Me</label>
                                                    </div>
                                                </div>
                                            </div><button className="btn btn-dark btn-block text-white btn-user" type="submit">Login</button>
                                            <hr />
                                        </form>
                                        <div className="text-center"><Link to="/register" className="small" href="register.html">Create an Account!</Link></div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>

        </Fragment >
    )
}
Login.propTypes = {
    login: PropTypes.func.isRequired,
    isAuthenticated: PropTypes.bool
}

const mapStateToProps = state => ({
    isAuthenticated: state.auth.isAuthenticated

})

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

我无法弄清楚这是否与我更改的路线结构有关,还是我错过了更大的问题。

【问题讨论】:

  • 请尝试将导入重写为import { login as loginAC} from '../../actions/auth',并在连接中使用它,如export default connect(mapStateToProps, { login: loginAC })(Login)
  • 这种情况下错误消失了,但是auth.js中的登录函数没有被调用。

标签: reactjs react-redux react-router react-hooks


【解决方案1】:

您已在 AppRoutes 中将 Login 导入为命名导入,而使用 Login 连接的组件是默认导出,这就是您看到问题的原因

改变

import { Login } from '../auth/Login'

import Login from '../auth/Login'

【讨论】:

  • 登录不是默认导出,该文件中有多个其他功能,如果我按照您说的做,它仍然会抛出此错误。:尝试导入错误:'../../ actions/auth' 不包含默认导出(作为 'login' 导入)。
  • 我说的是登录组件。根据您的代码,这是默认导出:export default connect(mapStateToProps, { login })(Login)
  • 很高兴能帮上忙
猜你喜欢
  • 2019-12-15
  • 2017-12-30
  • 2020-08-18
  • 2017-03-14
  • 2016-08-19
  • 2023-04-07
  • 2020-04-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多