Uncaught error actions must be plain objects use custom middleware for async actions

I am trying to resolve this issue. Am new to react. Here is my offer action import axios from 'axios'; // offers export const FETCH_OFFERS = 'FETCH_OFFERS'; export const FETCH_OFFER...

I am trying to resolve this issue. Am new to react.

Here is my offer action


import axios from 'axios';


// offers
export const FETCH_OFFERS = 'FETCH_OFFERS';
export const FETCH_OFFERS_SUCCESS = 'FETCH_OFFERS_SUCCESS';
export const FETCH_OFFERS_FAILURE = 'FETCH_OFFERS_FAILURE';
export const RESET_OFFERS = 'RESET_OFFERS';

// offer
export const FETCH_OFFER = 'FETCH_OFFER';
export const FETCH_OFFER_SUCCESS = 'FETCH_OFFER_SUCCESS';
export const FETCH_OFFER_FAILURE = 'FETCH_OFFER_FAILURE';
export const RESET_OFFER = 'RESET_OFFER';


const BASE_URL = location.href.indexOf('localhost') > 0 ? 'http://localhost:9001' : '';

export function fetchOffers(dispatch) {
	const request = axios({
		method: 'GET',
		url: `${BASE_URL}/offers`,
		headers: []
	});

	request.then((response) => {
		dispatch(fetchOffersSuccess(response));
	})
	.catch((err) => {
		dispatch(fetchOffersError(err))
	})

	return {
		type: FETCH_OFFERS,
		payload: request
	};
}

export function fetchOffersSuccess(offers) {
	return {
		type: FETCH_OFFERS_SUCCESS,
		payload: offers
	};
}

export function fetchOffersError(error) {
	return {
		type: FETCH_OFFERS_FAILURE,
		payload: error
	};
}

Root reducer

import { combineReducers } from 'redux';
import LoginReducer from '../components/login/LoginReducer';
// import HomeReducer from '../components/home/HomeReducer';
import OffersReducer from '../reducers/reducer_offers';
import event from './eventReducer';

export default combineReducers({
  currentUser: LoginReducer,
  offers: OffersReducer,
  event
});

store

import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import { composeWithDevTools } from 'redux-devtools-extension';
import rootReducer from './rootReducer';
import initialStore from './initialStore';

export default function configureStore() {

	
	return createStore(
	  rootReducer,
	  initialStore,
	  composeWithDevTools(
	    applyMiddleware(
	      thunk
	    )
	  )
	);
}

Reducers

import {
		FETCH_OFFERS, FETCH_OFFERS_SUCCESS, FETCH_OFFERS_FAILURE, RESET_OFFERS,
		FETCH_OFFER, FETCH_OFFER_SUCCESS, FETCH_OFFER_FAILURE, RESET_OFFER
	} from '../actions/offers';

	const INITIAL_STATE = { 
		offerList: {
			offers: [],
			error: null,
			loading: false
		},
		selectedOffer: {
			offer: null,
			error: null,
			loading: false
		}
	};

	export default function (state = INITIAL_STATE, action) {

		switch(action.type) {
			case FETCH_OFFERS:
				return {
					...state, offerList: {
						offers: [],
						error: null,
						loading: true
					}
				};
			case FETCH_OFFERS_SUCCESS:
				return {
					...state, offerList: {
						offers: action.payload,
						error: null,
						loading: false
					}
				};
			case FETCH_OFFERS_FAILURE:
				let error1 = action.payload || {message: action.payload.message}
				return {
					...state, offerList: {
						offers: [],
						error: error1,
						loading: false
					}
				};
			case RESET_OFFERS:
				return {
					...state, offerList: {
						offers: [],
						error: null,
						loading: false
					}
				};
			case FETCH_OFFER:
				return {
					...state, selectedOffer: {
						...state.selectedOffer,
						loading: true
					}
				};
			case FETCH_OFFER_SUCCESS:
				return {
					...state, selectedOffer: {
						offer: action.payload,
						error: null,
						loading: false
					}
				};
			case FETCH_OFFER_FAILURE: 
				let error2 = action.payload || {message: action.payload.message}
				return {
					...state, selectedOffer: {
						offer: null,
						error: error2,
						loading: false
					}
				};
			case RESET_OFFER:
				return {
					...state, selectedOffer: {
						offer: null,
						error: null,
						loading: false
					}
				};
			default: 
				return state;
		}
	}

error

I need help please

Answer by Tatum Daniel

Calling this always ended up in Actions must be plain objects. Use custom middleware for async actions.].,Redux-Thunk is the most popular middleware, because it helps us work with asynchronous action creators.,

Questions

So instead of just this:

    export const fetchPosts = async () => {
      const response  = await jsonPlaceholder.get('/posts');
      return {
        type: 'FETCH_POSTS',
        payload: response
      }
    };

with Redux-Thunk you would include this:

    export const fetchPosts = async () => {
      return function(dispatch, getState) {
        const response  = await jsonPlaceholder.get('/posts');
        return {
          type: 'FETCH_POSTS',
          payload: response
        }
      }
    };

So for me to properly apply Redux-Thunk to the example I gave you I would go to my root index.js file and import after installing it in terminal like so:

    import React from "react";
    import ReactDOM from "react-dom";
    import { Provider } from "react-redux";
    import { createStore, applyMiddleware } from "redux";
    import thunk from 'redux-thunk';
    
    import App from "./components/App";
    import reducers from "./reducers";
    
    ReactDOM.render(
      <Provider store={createStore(reducers)}>
        <App />
      </Provider>,
      document.querySelector("#root")
    );

So then I apply the createStore up front into a variable called store and implement that inside the Provider store like so:

    const store = createStore(reducers);
    
    ReactDOM.render(
      <Provider store={store}>
        <App />
      </Provider>,
      document.querySelector("#root")
    );

To hook up Redux-Thunk, as a second argument I will call applyMiddleware and pass in thunk like so:

    const store = createStore(reducers, applyMiddleware(thunk));
    
    ReactDOM.render(
      <Provider store={store}>
        <App />
      </Provider>,
      document.querySelector("#root")
    );

So rather than returning an action I can call dispatch and pass in my action object like so:

    export const fetchPosts = () => {
      return async function(dispatch, getState) {
        const response  = await jsonPlaceholder.get('/posts');
        
        dispatch({type: 'FETCH_POSTS', payload: response })
      }
    };

A common way of refactoring what I just shared above is like so:

    export const fetchPosts = () => {
      return async (dispatch) => {
        const response  = await jsonPlaceholder.get('/posts');
    
        dispatch({type: 'FETCH_POSTS', payload: })
      }
    };

So if you don’t make use of getState within the function, you can leave it out as an argument. You can make your code even more concise like so:

    export const fetchPosts = () => async dispatch => {
        const response  = await jsonPlaceholder.get('/posts');
        
        dispatch({type: 'FETCH_POSTS', payload: response })
    } 

Answer by Lena Harmon

Unhandled Rejection (Error): Actions must be plain objects. Use custom middleware for async actions.,Here is an example of async action using redux-thunk middleware.,You can’t use fetch in actions without middleware. Actions must be plain objects. You can use a middleware like redux-thunk or redux-saga to do fetch and then dispatch another action.

This would work:

export function bindComments(postId) {
    return function(dispatch) {
        return API.fetchComments(postId).then(comments => {
            // dispatch
            dispatch({
                type: BIND_COMMENTS,
                comments,
                postId
            });
        });
    };
}

Answer by Alden Chapman

I am trying to resolve this issue. Am new to react.,Here is my offer action,Successfully merging a pull request may close this issue.


import axios from 'axios';


// offers
export const FETCH_OFFERS = 'FETCH_OFFERS';
export const FETCH_OFFERS_SUCCESS = 'FETCH_OFFERS_SUCCESS';
export const FETCH_OFFERS_FAILURE = 'FETCH_OFFERS_FAILURE';
export const RESET_OFFERS = 'RESET_OFFERS';

// offer
export const FETCH_OFFER = 'FETCH_OFFER';
export const FETCH_OFFER_SUCCESS = 'FETCH_OFFER_SUCCESS';
export const FETCH_OFFER_FAILURE = 'FETCH_OFFER_FAILURE';
export const RESET_OFFER = 'RESET_OFFER';


const BASE_URL = location.href.indexOf('localhost') > 0 ? 'http://localhost:9001' : '';

export function fetchOffers(dispatch) {
	const request = axios({
		method: 'GET',
		url: `${BASE_URL}/offers`,
		headers: []
	});

	request.then((response) => {
		dispatch(fetchOffersSuccess(response));
	})
	.catch((err) => {
		dispatch(fetchOffersError(err))
	})

	return {
		type: FETCH_OFFERS,
		payload: request
	};
}

export function fetchOffersSuccess(offers) {
	return {
		type: FETCH_OFFERS_SUCCESS,
		payload: offers
	};
}

export function fetchOffersError(error) {
	return {
		type: FETCH_OFFERS_FAILURE,
		payload: error
	};
}


Answer by Robin Solis

If you get actions must be plain objects. use custom middleware for async actions error, here is how to fix this issue.,Then setup the middleware on your root redux configuration:,Building and using custom React hooks in our application

This error exists because you try to return a non-plain object on a redux action. For example, if you try to return another function, especially an async function, inside this action, redux doesn’t know how to handle this natively.

// redux action that returns async function
export const myAction = (payload) => async (dispatch) => {
  // your action
}
// installing redux-thunk dependency
npm install --save redux-thunk

Then setup the middleware on your root redux configuration:

// importing libraries
import { createStore, applyMiddleware } from 'redux'; 
import thunk from 'redux-thunk'; 
import rootReducer from './reducers/index'; 

// creating the redux store
const store = createStore( 
    rootReducer, 
    applyMiddleware(thunk) 
);

Answer by Uriah Thornton

An action informing that the asynchronous task:,As you can see, they represent the three phases we described above.
Let’s now define an action creator for Thunk:,Redux Thunk elegantly solves the problem of managing asynchronous actions in Redux. However, it forces you to make the action creator’s code more complicated by sending the HTTP request and handling the response.


  <div>
  Ron Swanson says:
  <blockquote id="quote"></blockquote>
</div>

Answer by Kaiser Clements

More Details Refer


Answer by Koda Odom

I get this error «Uncaught Error: Actions must be plain objects. Use custom middleware for async actions.» while running this code,Without the formatting it’s hard to read, but just make sure the helper functions you’re using to generate the objects to dispatched always return an object, not another function. For the most part, it seems that’s the case. How about these 2 functions:,I think the acorewct answer is thunk as is necessary for asynchronous actions

Without the formatting it’s hard to read, but just make sure the helper functions you’re using to generate the objects to dispatched always return an object, not another function. For the most part, it seems that’s the case. How about these 2 functions:

//SORT_BY_DATE
const sortByDate = () => {{
type: 'SORT_BY_DATE'
}};
//SORT_BY_AMOUNT
const sortByAmount = () => {{
type: 'SORT_BY_AMOUNT'
}};

Perhaps you’ve forgotten to surround the returned objects in parens?

//SORT_BY_DATE
const sortByDate = () => ({
type: 'SORT_BY_DATE'
});
//SORT_BY_AMOUNT
const sortByAmount = () => ({
type: 'SORT_BY_AMOUNT'
});

Answer by Everest Duke

Here is an example of async action using redux-thunk middleware.,You can’t use fetch in actions without middleware. Actions must be plain objects. You can use a middleware like redux-thunk or redux-saga to do fetch and then dispatch another action.,You have to dispatch after the async request ends.

This would work:

export function bindComments(postId) {
    return function(dispatch) {
        return API.fetchComments(postId).then(comments => {
            // dispatch
            dispatch({
                type: BIND_COMMENTS,
                comments,
                postId
            });
        });
    };
}

actions.js:

export function addNewComponent() {
  return {
    type: ADD_NEW_COMPONENT,
  };
}

myComponent.js:

import React, { useEffect } from 'react';
import { addNewComponent } from '../../redux/actions';

  useEffect(() => {
    dispatch(refreshAllComponents); // <= Here was what I've missed.
  }, []);

I’ve forgotten to dispatch the action function with (). So doing this solved my issue.

  useEffect(() => {
    dispatch(refreshAllComponents());
  }, []);

Here is an example of async action using redux-thunk middleware.

export function checkUserLoggedIn (authCode) {
 let url = `${loginUrl}validate?auth_code=${authCode}`;
  return dispatch => {
    return fetch(url,{
      method: 'GET',
      headers: {
        "Content-Type": "application/json"
      }
      }
    )
      .then((resp) => {
        let json = resp.json();
       if (resp.status >= 200 && resp.status < 300) {
          return json;
        } else {
          return json.then(Promise.reject.bind(Promise));
        }
      })
      .then(
        json => {
          if (json.result && (json.result.status === 'error')) {
            dispatch(errorOccurred(json.result));
            dispatch(logOut());
          }
          else{
            dispatch(verified(json.result));
          }
        }
      )
      .catch((error) => {
        dispatch(warningOccurred(error, url));
      })
  }
}

Answer by Milena Watkins

Actions must be plain objects. You can use a middleware like redux-thunk or redux-saga to do fetch and then dispatch another action.,
Object to Primitive Conversions in JavaScript
,You must dispatch after async request ends.

Facing below error:

Unhandled Rejection (Error): Actions must be plain objects. Use custom middleware for async actions.

I wanted to add comments with all posts. So when fetch posts are run I want to call fetch comment API for every post.

export function bindAllComments(postAllId) {
  return API.fetchComments(postAllId).then(comments => {
    return {
      type: BIND_COMMENTS,
      comments,
      posAlltId
    }
  })
}

Answer by Bruno Wiley

More Details Refer


I get this error «Uncaught Error: Actions must be plain objects. Use custom middleware for async actions.» while running this code

import { createStore, combineReducers } from ‘redux’;
import uuid from ‘uuid’;
// Add_Expense
const addExpense = (
{
description = »,
note = »,
amount = 0,
createdAt = 0
} = {}
) => ({
type: ‘ADD_EXPENSE’,
expense: {
id: uuid(),
description,
note,
amount,
createdAt
}
});
//Remove_Expense
const removeExpense = ({ id } = {}) => ({
type: ‘REMOVE_EXPENSE’,
id
});
//EDIT_EXPENSE
const editExpense = (id, updates) => ({
type: ‘EDIT_EXPENSE’,
id,
updates
});
//SET_TEXT_FILTER
const setTextFilter = (text = ») => ({
type: ‘SET_TEXT_FILTER’,
text
});
//SORT_BY_DATE
const sortByDate = () => {{
type: ‘SORT_BY_DATE’
}};
//SORT_BY_AMOUNT
const sortByAmount = () => {{
type: ‘SORT_BY_AMOUNT’
}};
const expensesReducerDefaultState = [];
const expensesReducer = (state = expensesReducerDefaultState, action) => {
switch (action.type) {
case ‘ADD_EXPENSE’:
return [
…state,
action.expense
];
case ‘REMOVE_EXPENSE’:
return state.filter(({ id }) => id !== action.id);
case ‘EDIT_EXPENSE’:
return state.map((expense) => {
if (expense.id === action.id) {
return {
…expense,
…action.updates
};
} else {
return expense;
};
});
default:
return state;
}
};
// Filters Reducer
const filtersReducerDefaultState = {
text: »,
sortBy: ‘date’,
startDate: undefined,
endDate: undefined
};
const filtersReducer = (state = filtersReducerDefaultState, action) => {
switch (action.type) {
case ‘SET_TEXT_FILTER’:
return {
…state,
text: action.text
};
case ‘SORT_BY_AMOUNT’:
return {
…state,
sortBy: ‘amount’
};
case ‘SORT_BY_DATE’:
return {
…state,
sortBy: ‘date’
};
default:
return state;
}
};

// Store creation
const store = createStore(
combineReducers({
expenses: expensesReducer,
filters: filtersReducer
})
);
store.subscribe(() => {
console.log(store.getState());
});

const expenseOne = store.dispatch(addExpense({ description: ‘Rent’, amount: 100 }));
const expenseTwo = store.dispatch(addExpense({ description: ‘Coffee’, amount: 300 }));
store.dispatch(removeExpense({ id: expenseOne.expense.id }));
store.dispatch(editExpense(expenseTwo.expense.id, { amount: 500 }));
store.dispatch(setTextFilter(‘rent’));
store.dispatch(setTextFilter());
store.dispatch(sortByAmount());
store.dispatch(sortByDate());
const demoState = {
expenses: [{
id: ‘poijasdfhwer’,
description: ‘January Rent’,
note: ‘This is the final payment for that address’,
amount: 54502,
createdAt: 0
}],
filters: {
text: ‘rent’,
sortBy: ‘amount’, //date or amount
startDate: undefined,
endDate: undefined
}
};

Understanding this error message is key to understanding a lot of stuff in the world of Redux. This may even be an interview question you get asked in the future.

In reality, there are two things wrong with your action creator. The first thing wrong with your action creator is that your action creator is supposed to return plain JavaScript objects with a type property and optionally a payload property as well, but at present you are not returning an action from your action creator.

You might look at your code editor and look at the action creator and you may be thinking, are you looking at the same action creator as I am? It might look like you are returning an object with a type property, but in fact you are not.

Even though it looks like you are returning a JavaScript object, that is not the case.

Much of the code we write inside our editor is ES2015, 2016, 2017, 2018 and so on. The code you and I write gets transpiled down to es2015 syntax and thats what actually gets executed inside the browser.

So even though this function looks like its returning an object with a type property, in fact, after we transpile this to es2015 code, we are not.

Drop your asynchronous action creator into babeljs.io next time and you will see what I mean.

This is what is actually transpiling our code down to ES2015.

So inside of the code editor, you think you are executing the code you wrote but in fact, because you specifically have this async/await syntax, the entire function gets expanded to what you see on the right hand side of babeljs.io.

So when I say to you that your action creator is not returning a plain JavaScript object, its because you have that async/await syntax. Thats why your action creator is not working as expected.

So you return, not your action object when this is initially called. When your action creator gets called for the first time, you do not return the action object, instead, as you saw, you have some code inside that returns your request object. That is what gets returned — a request. You return the request from your action creator and that goes into the store.dispatch method.

Then the redux store looks at what was returned and says okay, is this a plain JavaScript object with only a type property? Well, in this case, no because we just returned the request object we did not return our action and thats why we ended up seeing the nasty red message saying Actions must be plain objects. So we did not return a plain object and actions must return plain objects. We returned a request object that probably has some fancy methods assigned to it and probably not a type property, so we definitely did not dispatch what we thought we were dispatching.

This is all because of the async/await syntax that you are using.

So that is issue number 1 with your action creator. As a result of using the async/await syntax which gets transpiled down to es5 code, what actually runs inside your browser is not what you think actually runs.

So we are dispatching a NOT Redux action, we are dispatching a random object that Redux does not care about.

So how do we properly make use of this middleware called Redux-Thunk? Before we answer that, let’s understand what a middleware is in the world of Redux.

A middleware is a plain JavaScript function that will be called with every single action that we dispatch. Inside that function, a middleware has the opportunity to stop an action from being dispatched, prevent it from going to any reducers, modify an action or manipulate an action in any way, shape or form.

Redux-Thunk is the most popular middleware, because it helps us work with asynchronous action creators.

Okay, so how does Redux-Thunk help us solve this problem?

Well, Redux-Thunk will relax the normal action creator rules or Redux which says, as I have been saying above, that an action creator must return action objects, it must have a type property and optionally, a payload property.

There is nothing intrinsic about Redux-Thunk, it allows us to do many things, one of them being handling action creators, but its not its primary purpose.

Once we have Redux-Thunk involved in our action creator it can return plain objects OR it can return functions.

You see where this is going?

So how does returning a function help?

So our action creator returns an «action» in the form of an object or function. That «action» will be sent to the dispatch function and eventually it will end up inside of Redux-Thunk.

Redux-Thunk will say, «hi action, are you a function or are you an object?» If the «action» tells Redux-Thunk its an object, Redux-Thunk will say, «well, thanks for stopping by, action, but I prefer to only deal with functions» and then Redux-Thunk will shove «action» towards the reducers.

Otherwise, Redux-Thunk will say, «oh so you are a function? Nice!» Redux-Thunk will then invoke your function and it passes the dispatch, getState functions as arguments. You were already given the syntax version of your answer, so allow me to offer a variation of it.

So instead of just this:

export const fetchPosts = async () => {
  const response  = await jsonPlaceholder.get('/posts');
  return {
    type: 'FETCH_POSTS',
    payload: response
  }
};

with Redux-Thunk you would include this:

export const fetchPosts = async () => {
  return function(dispatch, getState) {
    const response  = await jsonPlaceholder.get('/posts');
    return {
      type: 'FETCH_POSTS',
      payload: response
    }
  }
};

Now in the above example I am making an asynchronous request with my action creator to an outside API. So this dispatch has unlimited powers to change the data on the Redux side of our application.

You see me utilizing getState so you can also understand that in addition to dispatch, getState will return all of the data inside of your store. These two arguments have unlimited power inside our Redux application. Through dispatch we can change any data we want and through getState we can read any data we want.

Go to the source code of Redux-Thunk itself:
https://github.com/reduxjs/redux-thunk/blob/master/src/index.js

The above is all of Redux-Thunk. Only 6 to 7 lines do anything, the others are initialization steps, function declarations and export. On line 2 is a series of functions that return functions.

In the body of it, you see the logic of whats going on and it asks, did you dispatch and action and if so is it an action or a function?

Everything I described above is captured in the source code.

So for me to properly apply Redux-Thunk to the example I gave you I would go to my root index.js file and import after installing it in terminal like so:

import React from "react";
import ReactDOM from "react-dom";
import { Provider } from "react-redux";
import { createStore, applyMiddleware } from "redux";
import thunk from 'redux-thunk';

import App from "./components/App";
import reducers from "./reducers";

ReactDOM.render(
  <Provider store={createStore(reducers)}>
    <App />
  </Provider>,
  document.querySelector("#root")
);

Notice I also imported the applyMiddleware. This function is how we connect a middleware to Redux.

So then I apply the createStore up front into a variable called store and implement that inside the Provider store like so:

const store = createStore(reducers);

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.querySelector("#root")
);

To hook up Redux-Thunk, as a second argument I will call applyMiddleware and pass in thunk like so:

const store = createStore(reducers, applyMiddleware(thunk));

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.querySelector("#root")
);

Then inside my action creator I make one or two changes. I can still return an normal object with a type property, that is an option, with Redux-Thunk we can still make normal action creators that return objects, but we don’t have to return an action.

So rather than returning an action I can call dispatch and pass in my action object like so:

export const fetchPosts = () => {
  return async function(dispatch, getState) {
    const response  = await jsonPlaceholder.get('/posts');
    
    dispatch({type: 'FETCH_POSTS', payload: response })
  }
};

With Redux-Thunk we can use async/await syntax, because this syntax is only going to modify the return value of the inner function. Nothing from the function will ever get used. Redux-Thunk will not get a reference of what gets returned and make use of it, we can return or not return, its what we return from our outer function is what we care about.

A common way of refactoring what I just shared above is like so:

export const fetchPosts = () => {
  return async (dispatch) => {
    const response  = await jsonPlaceholder.get('/posts');

    dispatch({type: 'FETCH_POSTS', payload: })
  }
};

So if you don’t make use of getState within the function, you can leave it out as an argument. You can make your code even more concise like so:

export const fetchPosts = () => async dispatch => {
    const response  = await jsonPlaceholder.get('/posts');
    
    dispatch({type: 'FETCH_POSTS', payload: response })
} 

You will see this in a lot of Redux projects. Thats it.

I am making a React-redux component to embed in Laravel blade file. Where in the react side,

I am using redux with the thunk, When I try to get data without thunk from the Laravel route, it getting properly.

But When I use an axios request in the action creator to get data asynchronously. It gives the:

‘Uncaught Error: Actions must be plain objects. Use custom middleware for async actions.’

This is the entry component of the react side.

Entry.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

import reducer from '../store/reducers/reducer';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux';

import thunk from "redux-thunk";


const store = createStore(reducer, applyMiddleware(thunk)
+window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
);
// console.log(getState());

ReactDOM.render(
    <Provider store={store}>
        <App />
    </Provider>
    , document.getElementById('like_post'));

This is the App.js main component

import React, { Component } from "react";
import { connect } from "react-redux";
import PropTypes from 'prop-types';
import axios from 'axios';
import {getCurrentPostLikes} from '../store/actions/actions';

class App extends Component {
    constructor(props) {
        super(props)

        var domain = window.location.hostname;
        var url = window.location.pathname;
        var urlsplit = url.split("/");
        var post_slug = urlsplit[urlsplit.length - 1];

        this.state={
            post_slug: post_slug,
            post_likes:''
        }
    }

    kFormatter(num) {
        return num > 999 ? (num / 1000).toFixed(1) + 'k' : num
    }

    componentDidMount() {
        this.props.getCurrentPostLikes();
        // axios.get(`/api/get_post_likes/${this.state.post_slug}`)
        // .then(response => {
        //     console.log(response.data.likes);
        //     this.setState({
        //         post_likes: response.data.likes
        //     })
        // })
    }

  render() {
    return (
      <div className="App">
        <a href="javascript:"><img src="/images/love.svg" alt="post like" width="50px" height="50px"/></a>
        <p>{this.kFormatter(this.state.post_likes)}</p>
        <p><span>{this.props.likes}</span></p>
      </div>
    );
  }
}


export default connect(null, {getCurrentPostLikes})(App);
// export default connect( mapStateToProps, mapDispachToProps )(App);

This is the actions.js file /store/actions/actions.js

// types.js is also defined properly as
// export const GET_POST_LIKES = 'GET_POST_LIKES';

import axios from 'axios';
import {GET_POST_LIKES} from './types';

// Get current post likes
export const getCurrentPostLikes = () => dispatch => {
  return dispatch => {
    setTimeout(() => {
      axios.get(`/api/get_post_likes/2`)
          .then(res => {
              // console.log(response.data.likes);
              // console.log(getState());
            setTimeout(() => {
                dispatch({
                    type: GET_POST_LIKES,
                    payload: res.data.likes
                })
            }, 4000);
          })
          .catch(err => {
              dispatch({
                  type: GET_POST_LIKES,
                  payload: {}
              })
          })
    }, 3000);
  }
}

Tried this action creator also, but still same error

export const getCurrentPostLikes = () => {
  return dispatch => {
      axios.get(`/api/get_post_likes/2`)
          .then(res => {
                dispatch({
                    type: GET_POST_LIKES,
                    payload: res.data.likes
                })
          })
          .catch(err => {
              dispatch({
                  type: GET_POST_LIKES,
                  payload: {}
              })
          })
  }
}

This is the reducers.js file under /store/reducers/reducer.js

import { GET_POST_LIKES } from '../actions/types';

const initialState = {
    likes: null
};

const reducer = (state=initialState, action) => {
    const newState = {...state};

    switch(action.type){
        case 'GET_POST_LIKES':
            return {
                ...state,
                post: action.payload
            }

        case 'LIKE_UP':
            newState.likes += action.value
            break;
    }
    return newState;
};

export default reducer;

Now, This should return a field value of posts table, with post id = 2.

Понравилась статья? Поделить с друзьями:
  • Uncaught error a url property or function must be specified
  • Uncar dll вернул код ошибки 11
  • Unc ошибка mhdd
  • Unbuckling rear belt ошибка
  • Unbound local error