1.0.16 • Published 11 months ago

jotai-reform v1.0.16

Weekly downloads
-
License
MIT
Repository
github
Last release
11 months ago

Jotai Reform

This library aims to provide a new way of using Jotai.

Jotai in itself is an awesome state manager with the convenience of using atoms and making a store instantly. Although using Jotai is kind of different than other state management libraries.

Here are a few common issues with Jotai I face in my projects:

Bad code management. Because of the simple approach of using atom and useAtom hook, Jotai made it easy to mutate a state but soon in larger projects, devs start to lose track of their code. Look at this simple code example:

  const [result, setResult] = useAtom(resultAtom)

setResult((prev) => ({ ...prev, open: false }))

Do you have any idea what this code is about? Me neither! But I wrote that. Now this issue can be solved by wrapping the state change in a meaningfully named function:

 const closeModal = () => {
    setResult((prev) => ({ ...prev, open: false }))
  }

Great, now I know it's being used to close the modal. But wait, what about reusability like reducers or like we do in Zustand? What is i need to use this same functionality in multiple components?

// example in zustand
const useStore = create((set) => ({
  count: 1,
  closeModal: () => set((state) => ({ ...state, open: false })),
}))

// no need to redefine the closeModal and also it increased readability

Now Jotai doesn't give us this out of the box. Well, that's why you need to start using jotai-reform from now on. jotai-reform provides you multiple benefits of using Jotai with ease.

Let's see some of the functions of jotai-reform:

Initialization

// wrap your application with provider from `jotai-reform`

import { createStore } from "jotai";
import { Provider } from "jotai";
const store = createStore();

<Provider store={store}>
  <App />
</Provider>

// using with next js 
"use client";

import { createStore, Provider } from "jotai";
import React, { PropsWithChildren } from "react";

const store = createStore();

export default function JotaiProvider(props: PropsWithChildren) {
  return <Provider store={store}>{props.children}</Provider>;
}

createAtom

createAtom is a wrapper around atom:

    const [useStore, storeAtom] = createAtom(initialState, (set, states, get) => ({...methods}));

createAtom has 2 arguments: 1st is your initialState, 2nd is your methods.

What are methods?

Methods are like reducers to perform any actions in your store. like in the prev examples increment is a method

Return type of createAtom

createAtom returns an array with 2 elements:

const [useStore, storeAtom] = createAtom(initialState, (set, states, get) => ({
  increment() {
    set({ count: states.count + 1 });
  },
}))

Let's see it in action:

const [useStore, storeAtom] = createAtom({ count: 0 }, (set, states, get) => ({
  increment() {
    set({ count: states.count + 1 });
  },
}));

// use storeAtom with useAtom
const [state, setStates] = useAtom(storeAtom);

useStore

// calling useStore hook will give an array 
const [states, methods, setStates, resetStore] = useStore()

// get the states from states
console.log(states.count);

// use methods to call any methods
methods.increment()

// use setState to manually update the states
setStates(p => ({count: p + 1}))

// resetStore will reset the store to its initial state
resetStore()

Using methods in jotai-reform

// in createAtom you have to pass your methods to the callback function

createAtom({count: 0}, (set, states, get) => ({}))

// in this callback you will return an object with methods

createAtom({count: 0}, (set, states, get) => ({
    increment: () => set({count: 1}) // use set to update the state
}))

// by default set reassigns the store value with the new given value
// so the new value will be {count: 1}; if you had another value in that object, it will be removed

//Example
createAtom({count1: 0, count2: 0}, (set, states, get) => ({
    increment: () => set({count1: 1}) // new store value {count1: 1} (count2 is removed)
}))

// to fix this issue you can pass the states to the set function

//Example
createAtom({count1: 0, count2: 0}, (set, states, get) => ({
    increment: () => set({...states, count1: 1}) // new store value {count1: 1, count2: 0}
}))

// the states parameter gives you all the current states of that store `states.count`

// use of `get`
// Now sometimes you need a value from another store/atom; for that, you can use the get function

//Example 
createAtom({count1: 0, count2: 0}, (set, states, get) => ({
    increment: () => set({...states, count1: get(anotherStoreAtom).anyValueFromThatStore}) 
}))

useResetAtoms

Now out of the box, jotai doesn't support resetting selective atoms (not talking about resettable atoms) or resetting the entire store.

Imagine this: you have 5 atoms you have to reset after a user logs out. You can use atomWithReset, but yeah, good luck calling const reset = useResetAtom(myAtom) 5 times and the reset function 5 times as well.

Well, well, well, we have a new approach to reset multiple atoms:

const reset = useResetAtoms();

// call the reset function
reset();
// that's it; it will now reset the entire store

// but what if I just want to reset some particular atoms/stores? It's easy:
reset({resetAtoms: [atom1, atom2]})

// that's it; atom1 and atom2 will now be reset

// but what if I want to reset the entire store excluding some particular atoms?

// easy:
reset({ignoreAtoms: [atom1, atom2]})

// the entire store will now be reset except atom1 and atom2
1.0.16

11 months ago

1.0.15

11 months ago

1.0.13

11 months ago

1.0.12

11 months ago

1.0.11

11 months ago

1.0.10

11 months ago

1.0.9

11 months ago

1.0.8

11 months ago

1.0.7

11 months ago

1.0.6

11 months ago

1.0.5

11 months ago

1.0.4

11 months ago

1.0.3

11 months ago

1.0.2

11 months ago

1.0.1

11 months ago

1.0.0

11 months ago