doux

by yisar

yisar / doux

🦄 Simple reactivity system with composition API.

442 Stars 37 Forks Last release: Not found 325 Commits 7 Releases

Available items

No Items, yet!

The developer of this repository has not created any items for sale yet. Need a bug fixed? Help with integration? A different license? Create a request here:

logo

Doux CircleCI npm

Simple reactivity system with composition API.

Motivation

Hooks API has mental burden and unsolvable defects, this library can solve the following problems:

  • Heavy state and repeated initialization.

In hooks API, Hooks will be initialized repeatedly. If there is a complex state, rendering will be blocked.

const [complexState] = useState(heavyData) // blocked

In Composition API, every component return a render function, this function will be rerendered every time, and state is initialized only once.

const data = reactive({ count: 0 }) // once
return () => vdom // every time
  • State management and Context proplems.

Use doux, shared state is easiest, just move the reactive state to global namespace.

const store = reactive({
  count: 0,
})
const App = setup(() => {
  return () => (
    
store.count++}>+
) })

const A = setup(() => { return () =>

{store.count}
}) const B = setup(() => { return () =>
{store.count}
})

Use

npm i doux -S
import { setup, reactive } from 'doux'
import { render } from 'react-dom'

const App = setup(() => { const data = reactive({ count: 0 }) return () => (

{data.count}
data.count++}>+
) }) render(, document.getElementById('root'))

setup

Like memo or lazy, it receive a different composition compoent and return a new component

const App = setup(() => {
  return () => (
    
{data.count}
data.count++}>+
) })

the composition component is different from hooks component, it return a pure render function,

return () => vdom

Because closures, and from the second time on, the component will only reexecute this function.

This can solve the problem of repeated initialization rendering of hooks API.

For the closures, the reactive must from parent scope.

effect

effect is a watch wrapper, like useEffect, it supported sources:

effect([], (oldSrc, newSrc) => {
  console.log(oldSrc, newSrc)
})

It will return a cleanup callback, you can use it to cleanup effects.

const cleanup = watch()
cleanup(()=> do()) // run both unmount and before update

In some cases, we may also want to watch with sources

// getter
const state = reactive({ count: 0 })
watch(() => state.count, (count, prevCount) => do())

// ref const count = ref(0) watch(count, (count, prevCount) => do())

Finally you can cleanup watcher

Composition API

reactive

It reversed a object and return a proxy object

const data = reactive({ count: 0 })
console.log(data.count) // 0
data.count++
console.log(data.count) //1

watch

It accepts an effect function and run it when data changed.

const data = reactive({ count: 0 })
watch(() => console.log(data.count))
data.count++ // console 1

ref

ref is another type of reactive, it just return an value

const ref = ref(0)
console.log(ref.value) //0

computed

effect for reactive data, when deps changed, it will return a ref

const data = reactive({ count: 0 })
const double = computed(() => data.count * 2)
data.count++

Lifecycles

Noneed lifecycles, use effect like useeffect:

| watch | useEffect | | ----------------- | --------------------------- | | effect(f) | useEffect(f) | | effect([x],f) | useEffect(f,[x]) | | effect([],f) | useEffect(f,[]) | | cleanup = watch() | useEffect(() => cleanup,[]) |

License

MIT ©yisar inspired by vue-next

We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.