Closed cbdeveloper closed 3 years ago
@cbdeveloper could you provide a minimal example in a code sandbox to explain what you are looking for / why you want async support? In general using async updaters is a footgun, as explained here https://immerjs.github.io/immer/async (see also the vid). TBH I regret adding that to Immer in the first case :) It is best to do all the async work first, and then call the updater in the end.
@mweststrate Thanks for your reply. I have some form states where I'm usually handling with Redux (toolkit implements immer produce by default). I'm doing it in Redux because it's very convenient to decouple state update logic and form UI. It's a blog edit form and you can see the preview for post you are writing right next to it. It's a fully controlled form.
The form state is actually a local state, so it shouldn't necessarily be on my Redux store. So started looking for a way to move it out of my Redux store, and that's when I came upon this package. It's so convenient to build the UI and simply dispatch actions and thunks from it. And to have a formSlice
where all the state update is handled.
The main reason I need thunks is on my async
actions, which currently are:
dispatch(thunks.saveBlogPost());
dispatch(thunks.uploadImage()); // Thumbnail and other images
The image upload goes something like this:
import { ACTIONS as A } from "./formSlice"
const UPLOAD_POST_THUMBNAIL = ({ file } : UploadPostThumbnailParams)
: AppThunk => {
return async (dispatch,getState) => {
try {
dispatch(A.UPLOAD_POST_THUMBNAIL_START());
const src = await uploadImageToStorage(file,"blog");
dispatch(A.UPLOAD_POST_THUMBNAIL_SUCCESS({src, sizeKb}));
}
catch(err) {
dispatch(A.UPLOAD_POST_THUMBNAIL_FAILURE({error: err}));
}
};
};
Not sure this is the best way, but it works. And it feels like the nicest way of keeping the upload status in sync with my form.
Would you mind setting it up in a sandbox, I'm don't have experience with RTK so I don't know how the dispatch above and implementation below relate :). I'd expect if you have an event handler, that calls your async action, but passes the sync dispatch as argument, it should work fine?
It should be something like this:
https://codesandbox.io/s/old-water-f6w8s?file=/src/App.tsx
Besides the dispatch
, every thunk also get access to a getState()
function which can be used to get the current state
from the store.
Sorry, I don't really get the question yet, and don't see an useImmer in the example. I suspect it is better to file this issue at React's useReducer
itself, as we basically follow the same api, with just the convenience of applying produce to the reducer.
Hey everyone, thanks for making this package.
It would be nice to be able to also dispatch thunks from the
useImmerReducer
hook.Instead of dispatching an action, we would dispatch an async function, just like in
redux-thunk
.It would really help with
async
actions involving API calls.Is it possible?