GithubHelp home page GithubHelp logo

utkusahinformsort / xoid Goto Github PK

View Code? Open in Web Editor NEW

This project forked from xoidlabs/xoid

0.0 0.0 0.0 6 MB

Framework-agnostic state management library designed for simplicity and scalability ⚛

Home Page: https://xoid.dev

License: MIT License

JavaScript 10.59% TypeScript 89.41%

xoid's Introduction

Bundle Size Version Downloads Netlify License

xoid is a framework-agnostic state management library. X (though it's read as Z) in its name signifies the inspiration it draws from great projects such as ReduX, MobX and Xstate. It was designed to be simple and scalable. It has extensive Typescript support.

xoid is lightweight (~1kB gzipped), but quite powerful. It's composed of building blocks for advanced state management patterns. One of the biggest aims of xoid is to unify global state, local component state, and finite state machines in a single API. While doing all these, it also aims to keep itself approachable for newcomers. More features are explained below, and the documentation website.

To install, run the following command:

npm install xoid

or

yarn add xoid

Examples

Quick Tutorial

xoid has only 2 exports: create and use. This section will cover them, and the @xoid/react.

Atom

Atoms are holders of state. create function is used to create them.

import { create } from 'xoid'

const atom = create(3)
console.log(atom.value) // 3
atom.set(5)
atom.update(state => state + 1)
console.log(atom.value) // 6

Atoms can have actions, and with .use method they can be used.

import { create, use } from 'xoid'

const numberAtom = create(5, (atom) => ({
  increment: () => atom.update(s => s + 1),
  decrement: () => atom.update(s => s - 1)
}))

use(numberAtom).increment()

There's the .focus method, which can be used as a selector/lens. xoid is based on immutable updates, so if you "surgically" set state of a focused branch, changes will propagate to the root.

import { create } from 'xoid'

const atom = create({ deeply: { nested: { alpha: 5 } } })
const previousValue = atom.value

// select `.deeply.nested.alpha`
const alpha = atom.focus(s => s.deeply.nested.alpha)
alpha.set(s => s + 1)

// root state is replaced with new immutable state
assert(atom.value !== previousValue) // ✅
assert(atom.value.deeply.nested.alpha === 6) // ✅

Derived state

Atoms can be derived from other atoms. This API was heavily inspired by Recoil.

const alpha = create(3)
const beta = create(5)
// derived atom
const sum = create((get) => get(alpha) + get(beta))

Alternatively, .map method can be used to quickly derive the state from a single atom.

const alpha = create(3)
// derived atom
const doubleAlpha = alpha.map((s) => s * 2)

Subscriptions

For subscriptions, subscribe and watch are used. They are the same, except watch runs the callback immediately, while subscribe waits for the first update after subscription.

const unsub = atom.subscribe(
  (state, previousState) => { console.log(state, previousState) }
)

To cleanup side-effects, a function can be returned in the subscriber function. (Just like React.useEffect)

React integration

@xoid/react is based on two hooks. useAtom subscribes the component to an atom. If a second argument is supplied, it'll be used as a selector function.

import { useAtom } from '@xoid/react'

// in a React component
const state = useAtom(atom)

The other hook is useSetup. It can be used for creating local component state. It'll run its callback only once. If a second argument is supplied, it'll be used for communication between the closure (useSetup scope) and outside (React component scope).

import { useSetup } from '@xoid/react'

const App = (props: Props) => {
  const setup = useSetup(($props) => {
    // `$props` has the type: Atom<Props>
    // this way, we can react to `props.something` as it changes
    $props.focus(s => s.something).subscribe(console.log)

    const alpha = create(5)
    return { alpha }
  }, props)

  ...
}

useSetup is guaranteed to be non-render-causing. Atoms returned by that should be explicitly subscribed via useAtom hook.

Here, this is enough knowledge to start using xoid! You can refer to the documentation website for more.

More features

Pattern: Finite state machines

No additional syntax is required for state machines. Just use the good old create function.

import { create } from 'xoid'
import { useAtom } from '@xoid/react'

const createMachine = () => {
  const red = { color: '#f00', onClick: () => atom.set(green) }
  const green = { color: '#0f0', onClick: () => atom.set(red) }
  const atom = create(red)
  return atom
}

// in a React component
const { color, onClick } = useAtom(createMachine)
return <div style={{ color }} onClick={onClick} />

Redux Devtools integration

Import @xoid/devtools and set a debugValue to your atom. It will send values to the Redux Devtools Extension.

import { devtools } from '@xoid/devtools'
import { create, use } from 'xoid'
devtools() // run once

const atom = create(
  { alpha: 5 }, 
  (atom) => {
    const $alpha = atom.focus(s => s.alpha)
    return {
      inc: () => $alpha.update(s => s + 1),
      resetState: () => atom.set({ alpha: 5 })
      deeply: {
        nested: {
          action: () => $alpha.set(5)
        }
      } 
    }
  }
)

atom.debugValue = 'myAtom' // enable watching it by the devtools

const { deeply, incrementAlpha } = use(atom) // destructuring is no problem
incrementAlpha() // logs "(myAtom).incrementAlpha"
deeply.nested.action() // logs "(myAtom).deeply.nested.action"
atom.focus(s => s.alpha).set(25)  // logs "(myAtom) Update ([timestamp])

Why xoid?

  • Easy to learn
  • Small bundle size
  • Framework-agnostic
  • Extensive Typescript support
  • Easy to work with nested states
  • Computed values, transient updates
  • Can be used to express finite state machines
  • No middleware is required for async/generator stuff
  • Global state and local component state in the same API

Other packages

  • @xoid/react - React integration
  • @xoid/devtools - Redux Devtools integration
  • @xoid/lite - Lighter version with less features intended for library authors
  • @xoid/feature - A typesafe plugin system oriented in ES6 classes

Thanks

Following awesome projects inspired xoid a lot.

Thanks to Anatoly for the pencil&ruler icon #24975.

xoid's People

Contributors

drcmda avatar onurkerimov avatar dai-shi avatar gsimone avatar jeremyrh avatar lynncubus avatar dependabot[bot] avatar paulshen avatar dudeonyx avatar dashed avatar arjunsajeev avatar clawoflight avatar thebuilder avatar dios-david avatar dichuvichkin avatar tkdodo avatar venturalp avatar jherr avatar bugzpodder avatar jamesthomsondev avatar javierriveros avatar jensechu avatar johnrees avatar lswest avatar msutkowski avatar liinkiing avatar hasparus avatar stolinski avatar stfnsr avatar timomeh avatar

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.