Skip to content

Latest commit

 

History

History
47 lines (37 loc) · 2.01 KB

hooks.md

File metadata and controls

47 lines (37 loc) · 2.01 KB

React Hooks

  • There are 2 hooks in valtio-kit: useInstance and useSnapshot.
  • useInstance creates an instance of a reactive class. It also sets up any persistent effects declared in the reactive class, and cleans them up when the component unmounts.
  • useSnapshot creates a snapshot of a reactive instance. The snapshot is immutable and reactive. The immutable nature of snapshots makes them a great fit with the new React Compiler.
  • Only useSnapshot will trigger component re-renders. It tracks which values your component is actually using, and will re-run the component when those values change.
  • Often times, you need to hoist state into a component that's higher in the React component tree. This is where useInstance is especially handy. Since useInstance never re-renders your component, your React app is optimized to only re-render where the data is actually used. In other words, to achieve optimal performance, your React app will re-render as deep in the component tree as possible.
// src/state/AppState.state.ts
import { PartialDeep } from 'type-fest'
import { deepMerge } from './utils/deepMerge'

export const AppState = createClass(() => {
  const obj = { a: { b: 1, c: 2 } }

  subscribeKey(obj, 'a', () => console.log('a changed'))

  return {
    obj,
    patchObj(patch: PartialDeep<typeof obj>) {
      obj = deepMerge(obj, patch)
    },
  }
})

// src/App.tsx
import { useInstance, useSnapshot } from 'valtio-kit'
import { AppState } from './state/AppState.state'

function App() {
  // Create an instance and set up persistent effects.
  const state = useInstance(AppState)

  // Alternatively, you can use React Context to avoid prop drilling.
  return <LeafComponent state={state} />
}

function LeafComponent(props) {
  // The component that calls useSnapshot is the one that will
  // re-render when the used values change.
  const snapshot = useSnapshot(props.state)

  // Subscribe to changes in `obj.a.b` only.
  return <div>{snapshot.obj.a.b}</div>
}