@watch-state/react

State manager of React

Downloads in past

Stats

StarsIssuesVersionUpdatedCreatedSize
@watch-state/react
102.0.0-alpha.1a year ago3 years agoMinified + gzip package size for @watch-state/react in KB

Readme

Watch-State logo by Mikhail Lysikov
  @watch-state/react
 
NPM downloads changelog license tests
State manager for React 18+ based on watch-state
stars watchers

Install

npm
npm i @watch-state/react

Usage

useWatch

You can observe only function components, by useWatch hook.
```typescript jsx import { State } from 'watch-state' import { useWatch } from '@watch-state/react'
const show = new State(false) const toggleShow = () => show.value = !show.value
const AsideMenuButton = () => ( onClick={toggleShow} /> )
const AsideMenu = () => { const isShow = useWatch(show)
return isShow ? (
<div>Aside Menu</div>
) : null }
#### useWatcher

You can observe only function components, by `useWatcher` hook.

```typescript jsx
import { State } from 'watch-state'
import { useWatcher } from '@watch-state/react'

const show = new State(false)
const toggleShow = () => show.value = !show.value

const AsideMenuButton = () => (
  <button
    onClick={toggleShow}
  />
)

const AsideMenu = () => {
  const isShow = useWatcher(() => show.value)
  // here is the difference ^^^^^^^^^^^^^^^

  return isShow ? (
    <div>Aside Menu</div>
  ) : null
}

useNewState

useNewState helps to create a State inside react component.
```typescript jsx import { Observable } from 'watch-state' import { useWatch, useNewState } from '@watch-state/react' import { useEffect } from "react";
interface ChildProps { value: Observable }
const Parent = () => { console.log('Parent creates State once');
const state = useNewState(0)
useEffect(() => {
const t = setInterval(() => {
  state.value++
}, 1000)

return () => {
  clearInterval(t)
}
}, )
return (
<Test value={state}/>
) }
const Test = ({ value }: ChildProps) => { console.log('Test renders once and provides value to Child', value);
return (
<Child value={value}/>
) }
const Child = ({ value }: ChildProps) => { console.log('Child renders on value canges', value);
const currentValue = useWatch(value)
return (
<div>
  {currentValue}
</div>
) }
#### useNewCache

`useNewCache` helps to create a `Cache` inside a component.

```typescript jsx
import { State } from 'watch-state'
import { useWatch, useNewCache } from '@watch-state/react'

const name = new State('Mike')
const surname = new State('Deight')

const Parent = () => {
  const fullName = useNewCache(() => `${name.value} ${surname.value[0]}.`)
  // renders once
  return <Child fullName={fullName} />
}

interface ChildProps {
  fullName: Observable<string>
}

const Child = ({ fullName }: ChildProps) => {
  const value = useWatch(fullName)
  // renders when fullName canges
  return <div>{value}</div>
}

useNewCache also helps to combine props and Observable inside a component.
```typescript jsx import { State } from 'watch-state' import { useWatch, useNewCache } from '@watch-state/react'
const name = new State('Mike')
interface ParentProps { surname: string }
const Parent = ({ surname }: ParentProps) => { const fullName = useNewCache(() => ${name.value} ${surname[0]}., surname) // renders when surname changes return }
interface ChildProps { fullName: Observable }
const Child = ({ fullName }: ChildProps) => { const value = useWatch(fullName) // renders when fullName canges return
{value}
}
You can use all features [watch-state](https://www.npmjs.com/search?q=%40watch-state) ecosystem.

`Cache` example:

```typescript jsx
import { State, Cache } from 'watch-state'
import { useWatch } from '@watch-state/react'

const name = new State('Mike')
const surname = new State('Deight')
const fullName = new Cache(() => `${name.value} ${surname.value[0]}.`)

const User = () => {
  const value = useWatch(fullName)

  return (
    <>{value}</>
  )
}

@watch-state/history-api example:
```typescript jsx import { useWatch } from '@watch-state/react' import { locationPath, historyPush } from '@watch-state/history-api'
const goTest = () => { historyPush('/test') }
const User = () => { const path = useWatch(locationPath)
return (
<button onClick={goTest}>
  {path}
</button>
) }
[@watch-state/async](https://www.npmjs.com/package/@watch-state/async) example:

```typescript jsx
import { useWatch, useWatcher } from '@watch-state/react'
import Async from '@watch-state/async'

const api = new Async(
  () => fetch('/api/test')
    .then(r => r.json())
)

const User = () => {
  const value = useWatch(api)
  const loading = useWatcher(() => api.loading)
  const loaded = useWatcher(() => api.loaded)
  const error = useWatcher(() => api.error)
  
  if (error) {
    return <div>Error!</div>
  }
  
  if (!loaded) {
    return <div>Loading</div>
  }

  return (
    <div className={loading && 'loading'}>
      {value.some.fields}
    </div>
  )
}

Links

Issues

If you find a bug or have a suggestion, please file an issue on GitHub
issues