I'm having a hard time implementing Redux in a quiet large website.
I have components connected to the store using the useSelector API I use Reselect to write selectors.
The thing is I don't know where to trigger the bootstrap actions of a page for example.
I have a container made of stateless components, that only takes props and displays them. In the container, one could trigger all the actions to fetch data from an API. (using redux-thunk) The main issue is that the devs should list the actions to be triggered in order to display the page.
But I was wondering if I could just trigger the right action when trying to select data from the store:
export function getComment(state, id) {
const comments = state.comments;
if (comments[id]) {
return comments[id];
}
store.dispatch(CommentActions.getComment(id));
return undefined;
}
The components here just "hook" themselves to data in the store. If the data is already there, it is returned, otherwise the trigger the action that calls the API and returns undefined.
My main interrogation is whether or not this approach is an anti-pattern, i.e. selectors are not pure functions because they trigger side-effects, etc.
We have a least two re-renders, one with an undefined, and an other one when the API responds.
Thanks in advance!
In a typical Redux application, the logic for deriving data is usually written as functions we call selectors. Selectors are primarily used to encapsulate logic for looking up specific values from state, logic for actually deriving values, and improving performance by avoiding unnecessary recalculations.
Redux includes a utility function called bindActionCreators for binding one or more action creators to the store's dispatch() function. Calling an action creator does nothing but return an object, so you have to either bind it to the store beforehand, or dispatch the result of calling your action creator.
useSelector and useDispatch are a set of hooks to use as alternatives to the existing connect() higher-order component. The equivalent of map state to props is useSelector. It takes in a function argument that returns the part of the state that you want. The equivalent of map dispatch to props is useDispatch.
With useSelector() , returning a new object every time will always force a re-render by default. If you want to retrieve multiple values from the store, you can: Call useSelector() multiple times, with each call returning a single field value.
Dispatching inside reselect is not discussed in Redux official documentation, so it should not be considered good solution.
But there are solutions that very close to what you want to achieve. For example redux-async-loader or using React.Lazy with Redux.
General idea of both approaches is to move data fetching to connect
function (where reselect lives). In this term, both approaches are very close to what you trying to achieve with dispatching in reselect.
Redux-async-loader from my point of view is a bit simpler. It creates higher order component which wraps around connect
.
React.Lazy does essentially the same. In addition you can use Suspense
component to temporary display "data loading..." when you wait for data.
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