-
Hello everyone! 👋 I'm proposing a new feature for Jotai that would add transaction support, allowing users to batch multiple atom updates and commit or roll them back as a single unit of work. This would enhance Jotai's capabilities for more complex state management scenarios where atomic operations across multiple atoms are needed. MotivationWhen working with related state that spans multiple atoms, there are cases where we need to ensure that multiple updates happen together or not at all. Some examples include:
Currently, Jotai updates atoms individually, which can lead to intermediate states where only some atoms have been updated. A transaction system would solve this problem by allowing developers to queue multiple updates and apply them atomically. Proposed APIimport { beginTransaction, commitTransaction, rollbackTransaction } from 'jotai';
const countAtom = atom(0);
const statusAtom = atom('idle');
// Start a transaction
const transaction = beginTransaction();
// Queue updates (not applied yet)
transaction.set(countAtom, 10);
transaction.set(statusAtom, 'updated');
// Conditionally apply or discard all queued updates
if (someCondition) {
commitTransaction(transaction); // Both atoms update together
} else {
// This will also be done internally when an error occurs during commitTransaction.
rollbackTransaction(transaction); // No changes applied
} Technical Requirements
Implementation ConsiderationsWhile I'm still working through the implementation details, I'm thinking about:
Next StepsI'd like to get feedback from the community on:
If there's interest, I'd be happy to start working on a proof-of-concept implementation to demonstrate the functionality more concretely. Thanks for considering this proposal! 🙂 |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 14 replies
-
Since Jotai v2.11, const a1 = atom(0)
const a2 = atom(0)
const a3 = atom(0)
// batchedWrite commits when store.set completes
const action = atom(null, function batchedWrite(get,set) {
set(a1, 1)
set(a2, 1)
get(a2) // causes a2 to be set immediately
set(a3, 1)
})
store.set(batchedWrite) jotai-effect achieves batching by hooking into the flush store phase atomStateMap map and changedAtoms set. const buildingBlocks = INTERNAL_getBuildingBlocksRev1(store)
const storeHooks = INTERNAL_initializeStoreHooks(buildingBlocks[6])
const atomStateMap = buildingBlocks[0]
const changedAtoms = buildingBlocks[3]
const removeStoreHook = storeHooks.f.add(null, function handleStoreFlush() {
// allow rollback, undo, redo here
}) For your api, you may want to include the ability to batch across multiple stores. You might also want to consider how to handle async tasks. When should the transaction commit? You might want to commit in stages or conditionally. |
Beta Was this translation helpful? Give feedback.
-
Hi, thanks for the suggestion. FYI, it's not exactly the same, but I did adding the batch support with valtio-reactive for valtio. Also, there might be something to learn from jotai-history. |
Beta Was this translation helpful? Give feedback.
-
hey @dai-shi @dmaskasky , I have created the repo along with some tests to verify functionality. Please take a look when possible. Also I have migrated over the |
Beta Was this translation helpful? Give feedback.
Hi, I just sent an invitation. Please create
jotai-transaction
repo injotaijs
org.