0
votes

I am using redux-thunk and redux-promise together and somehow redux-thunk middleware does not get called and i get an error.

THIS IS MY SETUP

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')
);

THIS IS MY ACTION CREATOR

export const authUser =  () => { 

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

This is my Higher Order AUTH Component which renders another component and AFTER DISPATCHING ACTION IN ComponentDidMount, based on the results I want to change routes.

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))
}

AND FINALLY THIS IS THE ERROR I GET.

https://imgur.com/a/nTnv9kh OR https://prnt.sc/tkcs0m

(Unhandled Rejection (TypeError): this.props.dispatch(…).then is not a function )

If I dont use .then() in ComponentDidMount, then I get undefined. ALSO If I dispatch inside of AXIOS request by adding .then(), this is another error I get

(Error: Actions must be plain objects. Use custom middleware for async actions.) https://imgur.com/a/czlvHBj OR https://prnt.sc/tkcsqy

2
you are not passing the props. check this reactjs.org/docs/… use constructor.Monzoor Tamal
problem is not with dispatch function but .then(). I should be able to use that. I mean thats what I expect :DCan
The problem is in your axios call. github.com/axios/axios read the documentation. axios get returns a promise. use can use try catch or async await.Monzoor Tamal
should not It be handled by middlewares ?. It worked but now I get another error and I think I learned these concepts really wrong :(Can
can i get a upvote for that?Monzoor Tamal

2 Answers

0
votes

after adding async await to axios call It worked(I thought It should be handled by middlewares) but now I get another error in my Header component

    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)                                                                                                     

(Unhandled Rejection (TypeError): Cannot read property 'isAuth' of undefined) https://prnt.sc/tkd0bj

0
votes

problem1: The problem is in your axios call. enter link description here read the documentation. axios get returns a promise. use can use try catch or async await.

problem2:

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