i come from Reflux to Redux. in Reflux your business logic is exist only in store but in Redux its seems different..for example in "Redux" i have "async-action" and i implemented it with "redux-thunk" .
in one scenario i want to check something in my action and if that needed i send request to server and get some data. i this case i have to check my logic in my action and actually my business logic is exist in action and store together and its not good.. what is your solution?
for example i have checkbox and i check some condition and if the result is true i send a request to server here is my action code and as you see my business logic is on my Action and my Reducer:
export function onCheckboxClick({itemId}) {
return (dispatch, getState) => {
let state = getState().get('myReducer');
let myConditionResult = state.get('foods').get(0).get('test');//for exmaple check some condition in my store
dispatch({type: 'CHECKBOX_CLICK', itemId});// for change the checkbox checked
if (myConditionResult) {
myApi.deleteOrderItem({itemId}).then(()=> {
dispatch({type: 'DELETE_ORDER_ITEM_FULFILLED', itemId});
}).catch((err)=> {
console.log(err);
dispatch({type: 'DELETE_ORDER_ITEM_REJECTED', itemId});
});
}
};
}
thanks in advance
1. Logic inside the Component. You also import the action into this component file and map the action to props as well.
As of 2020, we specifically recommend putting as much logic as possible in reducers: Wherever possible, try to put as much of the logic for calculating a new state into the appropriate reducer, rather than in the code that prepares and dispatches the action (like a click handler).
You store the state of your app in redux. How you structure your state tree is up to you. You can think of the state tree as one giant javascript object. With redux, you would ideally store as little component state in your react components themselves and instead move that to the redux state tree.
Some users prefer to keep every single piece of data in Redux, to maintain a fully serializable and controlled version of their application at all times. Others prefer to keep non-critical or UI state, such as “is this dropdown currently open”, inside a component's internal state. Using local component state is fine.
Quoting the Redux FAQ entry on "how to split business logic between action creators and reducers":
There's no single clear answer to exactly what pieces of logic should go in a reducer or an action creator.
If you put all the logic in the action creator, you end up with fat action objects that declare the updates to the state. Reducers become pure, dumb, add-this, remove that, update these functions. They will be easy to compose. But not much of your business logic will be there. If you put more logic in the reducer, you end up with nice, thin action objects, most of your data logic in one place, but your reducers are harder to compose since you might need info from other branches. You end up with large reducers or reducers that take additional arguments from higher up in the state.
It's valid to dispatch an action that gets ignored by the reducers, and it's also valid to inspect the state first and decide to not dispatch an action. Ultimately, it does come down to what you're comfortable with.
Here's some opinionated answer which goes against redux recommendations.
TL;DR Neither
Longer answer: in so called async action invoked from middleware. In redux community it is known as "thunk" or "saga".
First, some definitions:
{ type: 'ACTION_TYPE', payload: { data } }
So, where do we call the business logic from?
If you look carefully, you'll notice that we don't need async action and async action creator. We can have a simple action that is handled directly in the middleware.
In middleware we can have a dedicated handler for each action. This handler behaves like async action but we don't call it so. Let's call it interactor.
So a new definition:
interactor: an abstraction of what is essentially async action in redux, but not redux-specific. Interactor fetches data, calls business logic and dispatches result "actions".
middleware = (...) => {
// if(action.type == 'HIGH_LEVEL')
interactors[action.name]({ dispatch, params: action.payload })
}
const interactors = {
async highLevelAction({ dispatch, params }) {
dispatch({ loading: true });
const data = await api.getData(params.someId);
const processed = myPureLogic(data);
dispatch({ loading: false, data: processed });
}
}
How to dispatch it:
dispatch({ type: 'HIGH_LEVEL', name: 'highLevelAction', { someId: 1 } })
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With