Reputation: 8297
export const FETCH_DB_BEGIN = 'FETCH_DB_BEGIN'
export const FETCH_DB_SUCCESS = 'FETCH_DB_SUCCESS'
export const FETCH_DB_FAILURE = 'FETCH_DB_FAILURE'
export const fetchDatabase = () => {
return dispatch => {
const profile_url = 'localhost:5000/profiles'
const release_url = 'localhost:5000/releases'
const emp_url = 'localhost:5000/users'
let promises = []
let options = {
headers: header,
method: 'get',
mode: 'cors',
body: null,
}
dispatch(fetchDbBegin());
// run the script async. change state when it's done.
let profile_promise = new Promise((resolve, reject) => {
fetch(profile_url, options)
.then(res => res.json())
.then(resText => {
// Use Dispatch Here?
})
}).catch(err => {
console.log(err)
})
promises.push(profile_promise)
// run the script async. change state when it's done.
let release_promise = new Promise((resolve, reject) => {
fetch(release_url, options)
.then(res => res.json())
.then(resText => {
})
}).catch(err => {
console.log(err)
})
promises.push(release_promise)
// run the script async. change state when it's done.
let emp_promise = new Promise((resolve, reject) => {
fetch(emp_url, options)
.then(res => res.json())
.then(resText => {
})
}).catch(err => {
console.log(err)
})
promises.push(emp_promise)
Promise.all(promises).then(values => {
console.log(values)
})
}
}
export const fetchDbBegin = () => ({
type: FETCH_DB_BEGIN
});
export const fetchDbSuccess = (data) => ({
type: FETCH_DB_SUCCESS,
payload: { data }
});
export const fetchDbFailure = (err) => ({
type: FETCH_DB_FAILURE,
payload: { err }
});
I am in a process of refactoring a React class component to use Redux
. It initially had all API calls inside the componentDidMount
and it was so messy.
I am using redux-thunk
to move this out from the class component.
The fetchDatabase
in my databaseAction.js
does everything that componentDidMount
did in the class component.
Normally if it was a single API call, I would have just dispatched the fetchDbSuccess
as the API call was done successfully. However, using Promise.All
which takes three async API calls, I am not sure whether I should
fetchProfileSuccess
, fetchReleaseSuccess
, and fetchUserSuccess
) and dispatch each one of them at the end of each Promise (the place where I put //Use Dispatch Here?
in the code.OR
fetchDbSuccess
when the Promise.all
gets resolved.If I choose to do 2, am I supposed to update all three states
in my reducer?
Thanks
Upvotes: 7
Views: 10464
Reputation: 78920
You should only dispatch and update state if you have code that cares about said state updates. For example, if you're just wanting to show a single spinner then have the spinner go away when fully completed, your user doesn't necessarily care about each atomic operation, so you don't need it reflected in state. If you have a UI that does show each, then you would want those extra dispatches.
By the way, your Promises look a bit overcomplicated. If you decide you don't need those extra state changes, you can simplify to this:
export const FETCH_DB_BEGIN = 'FETCH_DB_BEGIN'
export const FETCH_DB_SUCCESS = 'FETCH_DB_SUCCESS'
export const FETCH_DB_FAILURE = 'FETCH_DB_FAILURE'
export const fetchDatabase = () => {
return dispatch => {
dispatch(fetchDbBegin());
const urls = [
'http://localhost:5000/profiles',
'http://localhost:5000/releases',
'http://localhost:5000/users'
];
const options = {
headers: header,
method: 'get',
mode: 'cors',
body: null,
}
const fetchJson = url => fetch(url, options).then(res => res.json());
Promise.all(urls.map(fetchJson))
.then(([profile, release, employee]) => {
dispatch(fetchDbSuccess({ profile, release, employee }));
})
.catch(err => {
dispatch(fetchDbFailure(err));
});
}
}
export const fetchDbBegin = () => ({
type: FETCH_DB_BEGIN
});
export const fetchDbSuccess = (data) => ({
type: FETCH_DB_SUCCESS,
payload: { data }
});
export const fetchDbFailure = (err) => ({
type: FETCH_DB_FAILURE,
payload: { err }
});
Upvotes: 7