I've utilized redux-promise-middleware with react and redux to build an application that has several buttons (each will have its own unique ajax request that will update the state accordingly)
I started to make the dataReducer for three of the many buttons I'm making. dataReducer is already over 100 lines and its also very tedious to make this reducer for the remainder of the buttons.
Is there a more efficient way of creating this dataReducer function and shortening while ensuring that the dataReducer function remains pure
const dataReducer = (state = dataInitialState, action) => {
console.log({ action_type: action.type });
switch (action.type) {
case "UPDATE_URL_ONE_PENDING":
return {
...state,
url_one: {
...state["url_one"],
error: false,
success: false,
loading: true
}
};
case "UPDATE_URL_ONE_FULFILLED":
console.log({ payload: action["payload"] });
return {
...state,
url_one: {
...state["url_one"],
error: false,
success: true,
loading: false,
payload: action["payload"]
}
};
case "UPDATE_URL_ONE_REJECTED":
return {
...state,
url_one: {
...state["url_one"],
error: true,
success: false,
loading: false
}
};
case "UPDATE_URL_TWO_PENDING":
return {
...state,
url_two: {
...state["url_two"],
error: false,
success: false,
loading: true
}
};
case "UPDATE_URL_TWO_FULFILLED":
return {
...state,
url_two: {
...state["url_two"],
error: false,
success: true,
loading: false,
payload: action["payload"]
}
};
case "UPDATE_URL_TWO_REJECTED":
return {
...state,
url_two: {
...state["url_two"],
error: true,
success: false,
loading: false
}
};
case "UPDATE_URL_THREE_PENDING":
return {
...state,
url_three: {
...state["url_three"],
error: false,
success: false,
loading: true
}
};
case "UPDATE_URL_THREE_FULFILLED":
return {
...state,
url_three: {
...state["url_three"],
error: false,
success: true,
loading: false,
payload: action["payload"]
}
};
case "UPDATE_URL_THREE_REJECTED":
return {
...state,
url_three: {
...state["url_three"],
error: true,
success: false,
loading: false
}
};
default:
return state;
}
};
Full Code (Code Sandbox Here)
import React from "react";
import ReactDOM from "react-dom";
import { Provider, connect } from "react-redux";
import { createStore, applyMiddleware, combineReducers } from "redux";
import thunk from "redux-thunk";
import promise from "redux-promise-middleware";
//Action Creator
function updateData(url, type) {
console.log({ url, type });
return dispatch => {
dispatch({
type: type,
payload: $.ajax({
type: "GET",
url: url,
dataType: "json",
async: false
})
});
};
}
//App Component
class App extends React.Component {
render() {
return (
<div>
<button
onClick={() => {
console.log({ props: this.props });
}}
>
Check Props
</button>
<button
onClick={() => {
this.props.updateData(
"https://api.iextrading.com/1.0/stock/market/batch?symbols=TSLA&types=quote,stats,news,chart&range=1m&last=5",
"UPDATE_URL_ONE"
);
}}
>
UPDATE URL ONE
</button>
<button
onClick={() => {
this.props.updateData(
"https://api.iextrading.com/1.0/stock/market/batch?symbols=GE&types=quote,stats,news,chart&range=1m&last=5",
"UPDATE_URL_TWO"
);
}}
>
UPDATE_URL_TWO
</button>
<button
onClick={() => {
this.props.updateData(
"https://api.iextrading.com/1.0/stock/market/batch?symbols=PZZA&types=quote,stats,news,chart&range=1m&last=5",
"UPDATE_URL_THREE"
);
}}
>
UPDATE_URL_THREE
</button>
<button
onClick={() => {
this.props.updateData(
"https://api.iextrading.com/1.0/stock/market/batch?symbols=PZZA&types=quote,stats,news,chart&range=1m&last=5",
"UPDATE_URL_FOUR"
);
}}
>
UPDATE_URL_FOUR
</button>
<button
onClick={() => {
this.props.updateData(
"https://api.iextrading.com/1.0/stock/market/batch?symbols=PZZA&types=quote,stats,news,chart&range=1m&last=5",
"UPDATE_URL_FIVE"
);
}}
>
UPDATE_URL_FIVE
</button>
<button
onClick={() => {
this.props.updateData(
"https://api.iextrading.com/1.0/stock/market/batch?symbols=PZZA&types=quote,stats,news,chart&range=1m&last=5",
"UPDATE_URL_SIX"
);
}}
>
UPDATE_URL_SIX
</button>
<button
onClick={() => {
this.props.updateData(
"https://api.iextrading.com/1.0/stock/market/batch?symbols=PZZA&types=quote,stats,news,chart&range=1m&last=5",
"UPDATE_URL_SEVEN"
);
}}
>
UPDATE_URL_SEVEN
</button>
<button
onClick={() => {
this.props.updateData(
"https://api.iextrading.com/1.0/stock/market/batch?symbols=PZZA&types=quote,stats,news,chart&range=1m&last=5",
"UPDATE_URL_EIGHT"
);
}}
>
UPDATE_URL_EIGHT
</button>
<button
onClick={() => {
this.props.updateData(
"https://api.iextrading.com/1.0/stock/market/batch?symbols=PZZA&types=quote,stats,news,chart&range=1m&last=5",
"UPDATE_URL_NINE"
);
}}
>
UPDATE_URL_NINE
</button>
<button
onClick={() => {
this.props.updateData(
"https://api.iextrading.com/1.0/stock/market/batch?symbols=PZZA&types=quote,stats,news,chart&range=1m&last=5",
"UPDATE_URL_TEN"
);
}}
>
UPDATE_URL_TEN
</button>
</div>
);
}
}
const mapStateToProps = state => state;
const mapDispatchToProps = dispatch => {
return {
updateData: (data, type) => {
dispatch(updateData(data, type));
}
};
};
const AppEnhanced = connect(
mapStateToProps,
mapDispatchToProps
)(App);
//reducer below that will determine how the state updates based on the action reducer above
const dataInitialState = {
url_one: { error: false, success: false, loading: true, payload: [] },
url_two: { error: false, success: false, loading: true, payload: [] },
url_three: { error: false, success: false, loading: true, payload: [] },
url_four: { error: false, success: false, loading: true, payload: [] },
url_five: { error: false, success: false, loading: true, payload: [] },
url_size: { error: false, success: false, loading: true, payload: [] },
url_seven: { error: false, success: false, loading: true, payload: [] },
url_eight: { error: false, success: false, loading: true, payload: [] },
url_nine: { error: false, success: false, loading: true, payload: [] },
url_ten: { error: false, success: false, loading: true, payload: [] }
};
const dataReducer = (state = dataInitialState, action) => {
console.log({ action_type: action.type });
switch (action.type) {
case "UPDATE_URL_ONE_PENDING":
return {
...state,
url_one: {
...state["url_one"],
error: false,
success: false,
loading: true
}
};
case "UPDATE_URL_ONE_FULFILLED":
console.log({ payload: action["payload"] });
return {
...state,
url_one: {
...state["url_one"],
error: false,
success: true,
loading: false,
payload: action["payload"]
}
};
case "UPDATE_URL_ONE_REJECTED":
return {
...state,
url_one: {
...state["url_one"],
error: true,
success: false,
loading: false
}
};
case "UPDATE_URL_TWO_PENDING":
return {
...state,
url_two: {
...state["url_two"],
error: false,
success: false,
loading: true
}
};
case "UPDATE_URL_TWO_FULFILLED":
return {
...state,
url_two: {
...state["url_two"],
error: false,
success: true,
loading: false,
payload: action["payload"]
}
};
case "UPDATE_URL_TWO_REJECTED":
return {
...state,
url_two: {
...state["url_two"],
error: true,
success: false,
loading: false
}
};
case "UPDATE_URL_THREE_PENDING":
return {
...state,
url_three: {
...state["url_three"],
error: false,
success: false,
loading: true
}
};
case "UPDATE_URL_THREE_FULFILLED":
return {
...state,
url_three: {
...state["url_three"],
error: false,
success: true,
loading: false,
payload: action["payload"]
}
};
case "UPDATE_URL_THREE_REJECTED":
return {
...state,
url_three: {
...state["url_three"],
error: true,
success: false,
loading: false
}
};
default:
return state;
}
};
const reducers = combineReducers({
data: dataReducer
});
const store = createStore(reducers, applyMiddleware(thunk, promise));
ReactDOM.render(
<Provider store={store}>
<AppEnhanced />
</Provider>,
document.getElementById("root")
);