Below is the code for my action creator:
export function fetchPosts()
{
const request = axios.get(`${ROOT_URL}/posts${API_KEY}`);
return
{
type: FETCH_POSTS;
payload: request
};
}
Next to type: FETCH_POSTS, if i add , instead of ; i get the error Unexpected token. Is that the syntax for action creators?
Then if i replace , with ; upon compile i get the error 'Actions must be plain Javascript Objects.
Any idea why?
GibboK's answer has already pointed out the syntax error.
However, I don't think you understand using actions properly. You run:
const request = axios.get(`${ROOT_URL}/posts${API_KEY}`);
This is creating a promise. You are currently returning this in an action. Reducers are meant to be deterministic & side effect free, hence why actions should be plain JS objects. You should not be submitting a promise.
Instead, you should be using some relevant middleware, e.g. redux-thunk, redux-saga or something else. You should send an action when the actual promise has resolved.
As a simple contrived example, using redux-thunk
:
export const fetchPosts = () => (dispatch) => {
// Send action to notify request started. Reducers often want to
// update the state to record that a request is pending, e.g. for
// UI purposes.
dispatch({type: FETCH_POSTS_START});
// Start request
request = axios.get(`${ROOT_URL}/posts${API_KEY}`)
.then(res => {
// Successfully received posts, submit response data
dispatch({type: FETCH_POSTS_COMPLETE, payload: res.data})
})
.catch(err => {
// API call failed, submit error
dispatch({type: FETCH_POSTS_ERROR, payload: err})
});
};
Note this code is just an example and not necessarily suitable for use in a production system.
When you replace ,
with ;
you get an error because, as stated by your error message, an action must return a JavaScript object.
In JavaScript object properties should be separated by ,
as:
return
{
type: FETCH_POSTS, // use comma here
payload: request
};
In this way the return
statement will return a new object with two properties type
and payload
.
As per redux documentation:
Actions
are plain JavaScript objects. Actions must have a type
property
that indicates the type of action being performed. Types
should typically be defined as string constants
. Once your app is
large enough, you may want to move them into a separate module.
And Action Creators
Action creators are functions that create actions
In Redux action creators simply return an action:
function addTodo(text) {
return {
type: ADD_TODO,
text
}
}
So when you call the action creator
from your component through dispatch
your action creator just needs to simply return a plain javascript object.
So a normal action creator will be
export function fetchPosts()
{
return
{
type: FETCH_POSTS;
payload: "somevalue"
};
}
Now if you want to call APIs within your action creators you need to make use of middlewares like redux-thunk
or redux-saga
while creating a store
like
import thunk from 'redux-thunk';
const store = createStore(reducers, applyMiddleware(thunk));
You you configure your store with middleware you can modify your actions to
export function fetchPosts() {
return (dispatch) => {
axios.get(`${ROOT_URL}/posts${API_KEY}`)
.then((response)=> {
dispatch( {
type: FETCH_POSTS,
payload: request
})
})
}
}
As per the redux-thunk documentation
Why Do you need redux-thunk?
Redux Thunk middleware
allows you to write action creators that
return a function instead of an action. The thunk can be used to delay
the dispatch
of an action, or to dispatch
only if a certain
condition is met. The inner function receives the store methods
dispatch and getState
as parameters
.