【问题标题】:Unhandled Rejection (TypeError): this.props.dispatch(...).then is not a function未处理的拒绝(TypeError):this.props.dispatch(...).then 不是函数
【发布时间】:2020-11-08 08:51:49
【问题描述】:

我同时使用 redux-thunk 和 redux-promise,不知何故 redux-thunk 中间件没有被调用,我得到一个错误。

这是我的设置

import React from 'react';
import ReactDOM from 'react-dom';
import {BrowserRouter} from 'react-router-dom'
import {Provider} from 'react-redux'
import { composeWithDevTools } from 'redux-devtools-extension';
import {createStore, applyMiddleware} from 'redux'
import thunk from 'redux-thunk'
import promiseMiddleware from 'redux-promise';

import {ThemeProvider} from "@material-ui/core/styles"
import theme from "./components/ui/Theme"
import reducers from './reducers/index'
import './index.css';
import App from './App';

const middleware =[thunk, promiseMiddleware]

const store = createStore(
  reducers,
  composeWithDevTools(applyMiddleware(...middleware))
)



ReactDOM.render(
  <Provider store={store}>
    <ThemeProvider theme={theme}>
      <BrowserRouter>
        <App />
      </BrowserRouter>
    </ThemeProvider>
  </Provider>  
  ,
  document.getElementById('root')
);

这是我的动作创作者

export const authUser =  () => { 

    const res = axios.get("http://localhost:3002/api/users/auth", {withCredentials: true})
      
    return {type: AUTH_USER, payload: res.data}
}

这是我的高阶 AUTH 组件,它根据我想要更改路线的结果呈现另一个组件并在 ComponentDidMount 中调度操作之后。

import React from 'react'
import {connect} from 'react-redux'
import {withRouter} from 'react-router-dom'

import CircularProgress from '@material-ui/core/CircularProgress';
import {authUser} from '../actions/user'


export default function(WrappedComponent, isRestricted){
    class Auth extends React.Component {

    state = {
        loading: true
    }
    
        componentDidMount() {
        
        this.props.dispatch(authUser()).then(() => {
            this.setState({loading: false})
            
            // if(!this.props.user.isAuth && isRestricted) {
            //     this.props.history.push('/joinus')
            // }
            // else if (this.props.user.isAuth && isRestricted === null) {
            //     this.props.history.push('/')
            // }
        }) 
    }

    render() {

        if(this.state.loading) {
        
            return (
                <CircularProgress />
            )
        }


        return (
            <div>
                <WrappedComponent  {...this.props} />
            </div>
        )
    }  
        
    }

    function mapStateToProps (state) {
        return {
            user: state.user.userData
        }
    }
    
    return  connect(mapStateToProps)(withRouter(Auth))
}

最后这是我得到的错误。

https://imgur.com/a/nTnv9khhttps://prnt.sc/tkcs0m

(Unhandled Rejection (TypeError): this.props.dispatch(...).then 不是函数 )

如果我不在 ComponentDidMount 中使用 .then(),那么我会得到未定义。此外,如果我通过添加 .then() 在 AXIOS 请求内部分派,这是我得到的另一个错误

(错误:操作必须是普通对象。使用自定义中间件进行异步操作。) https://imgur.com/a/czlvHBjhttps://prnt.sc/tkcsqy

【问题讨论】:

  • 你没有通过道具。检查这个reactjs.org/docs/… 使用构造函数。
  • 问题不在于调度函数,而是.then()。我应该可以使用它。我的意思是这就是我所期望的:D
  • 问题出在您的 axios 调用中。 github.com/axios/axios 阅读文档。 axios get 返回一个承诺。 use 可以使用 try catch 或 async await。
  • 不应该由中间件处理吗?它奏效了,但现在我又遇到了一个错误,我认为我学到的这些概念真的错了:(
  • 我可以为此投票吗?

标签: reactjs redux react-redux redux-thunk redux-promise-middleware


【解决方案1】:

在将 async await 添加到 axios 调用之后它起作用了(我认为它应该由中间件处理)但现在我的 Header 组件中出现另一个错误

    useEffect(() => {
        
        props.dispatch(actions.authUser()).then(() => {
            console.log(props, actions)
            if(props.user.isAuth) setToggleLogOut(true)
        })

        window.addEventListener('scroll', ()=> {
            window.scrollY > 0 ? setToggleHeader(true) : setToggleHeader(false)
        });
    }, [props.value])

    const handleLogOut = () => {
        props.logOutUser(() => {
            setToggleLogOut(false)
        })
    }


.
.
.
.
.
.
.
.


function mapStateToProps (state) {
    return {
        user: state.user.userData
    }
}

export default connect(mapStateToProps)(Header)                                                                                                     

(未处理的拒绝(TypeError):无法读取未定义的属性“isAuth”) https://prnt.sc/tkd0bj

【讨论】:

  • 我认为你需要更多地了解 redux 的工作原理。你的减速机在哪里。你更新你的减速器了吗?如果是这样,请使用此react-redux.js.org/api/hooks#useselector
  • prnt.sc/tkdkzo 这就是我的减速器的样子。在 Header 组件中触发调度后,我收到此错误,但在 redux dev-tools 中我可以看到调度已完成。所以 .then() 在这里不起作用。 prnt.sc/tkdklb
  • 我转换为 useSelector 所以这就是为什么在这个我没有 props.user 但 user*
  • 我在每个路由的标题和受保护路由中同时调用 authUser 操作。是这个问题吗?
【解决方案2】:

问题 1:问题出在您的 axios 调用中。 enter link description here 阅读文档。 axios get 返回一个承诺。 use 可以使用 try catch 或 async await。

问题2:

const authData = useSelector(state => state.user)
const [isLoading, setIsLoading] = useState(true)

useEffect(() => {
   if(authData.isAuth) {
      setIsLoading(false)
   }

}, [authData]);

if(isLoading) return <p>loading...</p>

// your rest of code

【讨论】:

  • 由于isAuth的第一个值是未定义的,总是会报错。我们应该在达到条件部分之前以某种方式延迟,但是 .then() 不起作用。它可以通过动作创建者内部的回调来解决,但那有什么意义呢。中间件确实有些奇怪(thunk,promise)
  • 创建沙盒代码。将在那里看到主要问题
猜你喜欢
  • 2018-12-09
  • 2021-10-14
  • 2020-11-16
  • 2020-05-06
  • 2019-10-27
  • 2020-09-26
  • 2021-04-16
  • 2021-03-09
  • 1970-01-01
相关资源
最近更新 更多