Async Reducer
#3021
-
I had this idea of using async reducers: type State = { step: "IDLE" | "LOADING" | "VERIFY_EMAIL" | "SELECT_METHOD" }
type Action = { type: "OPEN_SETUP_DRAWER" }
const mfaAtom = atomWithAsyncReducer<State, Action>(
async function* reducer(action) {
if (action.type === "OPEN_SETUP_DRAWER") {
// the value you yield is essentially the atom’s set function
// must be a fn that takes the current state to ensure access to the latest state
yield (s) => ({ ...s, step: "LOADING" })
const { isEmailVerified } = await getUserInfo()
const nextStep = isEmailVerified ? "SELECT_METHOD" : "VERIFY_EMAIL"
// the value you return is essentially the atom’s set function
// must be a fn that takes the current state to ensure access to the latest state
return (s) => ({ ...s, step: nextStep })
}
return (s) => s
},
/* initialState: */ { step: "IDLE" }
) This is my implementation of import { atom } from "jotai"
function atomWithAsyncReducer<S, A>(
reducer: (action: A) => AsyncGenerator<(s: S) => S, (s: S) => S, never>,
initialState: S
) {
const stateAtom = atom(initialState)
const dispatchAtom = atom(
(get) => get(stateAtom),
async (_get, set, action: A) => {
const generator = reducer(action)
let result = await generator.next()
while (!result.done) {
set(stateAtom, result.value)
result = await generator.next()
}
set(stateAtom, result.value)
}
)
return dispatchAtom
} @dai-shi Do you think this implementation has any flaws? In theory, this removes the need for async actions in favor of “async reducers.” The reducer itself isn’t truly async since each |
Beta Was this translation helpful? Give feedback.
Answered by
dai-shi
Mar 10, 2025
Replies: 1 comment
-
No. It looks just good. I'm not sure if it's called async reducer, but calling |
Beta Was this translation helpful? Give feedback.
0 replies
Answer selected by
hnordt
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
No. It looks just good. I'm not sure if it's called async reducer, but calling
set
multiple times in the atom write function is fine.