Giter Club home page Giter Club logo

klyva's Introduction

πŸͺ“ klyva

Scalable state management for React.

Minimal API, with reactive, composable and decomposable state!

πŸ“Ί 10 minute tutorial

How to

Create an atom

A base atom can be constructed by giving the atom a value.

const countAtom = atom(5)

useAtom

The useAtom hook subscribes to changes to the atom, so if it's updated, then this component is notified and updated. The hook is similar to react's useState in that it gives a setState function.

const MyComponent = () => {
  const [value, setValue] = useAtom(countAtom)
  const increase = () => setValue(oldValue => oldValue + 1)
  return <button onClick={increase}>{value}</button>
}

Composition

Atoms are composable. Meaning that you can glue together two atoms using the get function, when any dependant atoms are updated, the derived atom is updated:

const atomOne = atom(10)
const atomTwo = atom(20)
const sumAtom = atom(get => get(atomOne) + get(atomTwo))

Decomposition

You can focus on a smaller part of an atom, to view and update that smaller part (focusedAtom) - which in turn updates the derivee (objectAtom).

const objectAtom = atom({a: 10})
const focusedAtom = focusAtom(objectAtom, optic => optic.prop('a'))

const MyComponent = () => {
  const [value, setValue] = useAtom(focusedAtom)
  const increase = () => setValue(oldValue => oldValue + 1)
  return <button onClick={increase}>{value}</button>
}

See more about optics at: https://github.com/akheron/optics-ts

Usage outside of react

Get value

Use the getValue function to get the atoms current value:

const counterAtom = atom(0)
counterAtom.getValue() // 0

Update it

Atoms have an update function, which can be used to update it outside of react:

const numberAtom = atom(5)

numberAtom.update(6)
numberAtom.update(value => value + 1)

Subscribe

Use the subscribe function to subscribe to changes for this atom:

const counterAtom = atom(0)
counterAtom.subscribe(count => console.log(`The count is: ${count}`))
counterAtom.update(count => count + 1)
// console: The count is: 1

Advanced example

When you have an atom which contains a list, and you want to delegate control of each list item, you can use the useAtomSlice-hook like this:

const listAtom = atom([0,0,0])

const CounterList = () => {
  const counterAtoms = useAtomSlice(listAtom)
  const addCounter = () => listAtom.update(counters => [...counters, 0])
  return (
    <>
      <ul>
        {counterAtoms.map((atom) => <Counter counterAtom={atom} onRemove={atom.remove} />)}
      </ul>
      <button onClick={addCounter}>
        Add counter
      </button>
    </>
  )
}

const Counter = ({counterAtom, onRemove}: {counterAtom: Atom<number>, onRemove: () => void}) => {
  const [count, setCount] = useAtom(counterAtom)
  return (
    <li>
      <button onClick={() => setCount(v => v + 1)}>{count}</button>
      <button onClick={onRemove}>Remove me</button>
    </li>
  )
}

Curious? See codesandbox!

Differences from jotai and recoil

  • No <Provider> needed
  • No key needed for atom
  • More performant: Atoms are minimally expensive to create, and you can create them almost for free in react components.
  • Usage outside of react components is supported, so you can listen to changes and update atoms from outside of a react context.

Install

Using npm

npm i klyva

Using yarn

yarn add klyva

klyva's People

Contributors

krawaller avatar merisbahti avatar quaderi avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

klyva's Issues

Evangelism ideas

To capture the interest of developers, it would be beneficial if:

  1. Understanding is easy. Ideally the "above the fold" view of the repo (and npm / ... flutter pub page) is enough to be able to make use of the library.
  2. Dipping your toes is easy. Ideally an easy to remember import line, and "one line" changes in the actual code to use this library instead of whatever was in use before.
  3. Swapping is easy. Ideally some compatibility layer that would make it easy to just replace all usage of, say, React.useState with a klyva-based
  4. Switching over is easy - have something like a codemod approach for cleaning up after having started doing the above steps and decided to go all-in.

(We discussed this on Discord, and I plan to update this more a bit later)

Quick 5 minute tutorial

Make a 5 minute tutorial with associated starting code sandbox.

High level script:
What is klyva (simplified state management, basically just useState)
Start by building TodoItem component
Make that TodoItem take an atom as a prop (global state that feels local)
Expand and build TodoList

Docs

Create docs/*.md detailing:

  • Comparison to similar libraries (recoil, mobx, jotai)
  • Async (or why doesn't klyva have async atoms - atoms are cheap! you should just use useQuery or useSwr, or .server-components for data fetching!)
  • Explain why focusAtom and useAtomSlice, with prop drilling, enable you to build more testable apps.

Concurrent Mode compatibility? πŸ˜ƒ

In an older version of https://github.com/dai-shi/will-this-react-global-state-work-in-concurrent-rendering we had klyva included. At that time, klyva was passing all tests except this one:

check with useTransition
  βœ• check 7: proper branching with transition (6127 ms)

What is this test 7 checking? Is this something that is hard to fix in klyva? If it needs a de-optimisation, could it be as an optional extra or a plugin or monkeypatch under a contrib/ folder, so that klyva could be the first to pass all the known tests for concurrent mode? πŸŽ‰

missing dependencies: react & react-dom

the source code in "react-utils.ts" is importing and using both react and react-dom packages directly, but these packages are not included in the dependency field in your package.json (they are however located in devDependencies).

you could add them under peerDependencies field as ^16.8.3 to allow the end user to supply their own react/react-dom version from their project

Testing a klyva-app

If we assume jest, and optionally some jest-extension, what developer experience should there be for testing an app built with klyva?

Maybe something like klyva.resetAll() to move klyva state to initial? How would this be done with a redux-based app?

README.md suggestions

Some things that came up when trying out Klyva:

  • make optics part of the Klyva tagline. it's the thing that really sets this lib apart from all others. good to communicate that from the start.

  • considering optics is such a big thing in this library, I think it would be great to give some practical examples.

  • start examples with import statement, e.g.

import {atom} from 'klyva'

const countAtom = atom(5)
  • I know it's written in the docs but I still didn't parse it completely when I read it: it's if you want your component to update when an atom changes, you gotta use the useAtom or useSelector hook in that component.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.