unstated-fast
v0.0.3
Published
unstated-fast is a performance-enhanced version of unstated-next.
Downloads
11
Readme
Unstated Fast
unstated-fast is a performance-enhanced version of unstated-next.
unstated-next is awesome! However, when state is shared across large-scale components, any state change in Hooks triggers re-renders of all components sharing that state. unstated-fast elegantly solves this issue by leveraging React 18's new useSyncExternalStore feature.
Install
npm install --save unstated-fast
Example
import React, { useState } from "react";
import { createContainer } from "unstated-fast";
import { render } from "react-dom";
function useCounter(initialState = 0) {
let [count, setCount] = useState(initialState);
let decrement = () => setCount(count - 1);
let increment = () => setCount(count + 1);
return { count, decrement, increment };
}
let Counter = createContainer(useCounter);
function CounterDisplay() {
// component won't rerender untill count changed
let count = Counter.useContainer((state) => state.count);
return (
<div>
<span>{count}</span>
</div>
);
}
function CounterOperator() {
let counter = Counter.useContainer();
return (
<div>
<button onClick={counter.decrement}>-</button>
<button onClick={counter.increment}>+</button>
</div>
);
}
function App() {
return (
<Counter.Provider>
<CounterDisplay />
<Counter.Provider initialState={2}>
<div>
<div>
<CounterDisplay />
</div>
</div>
</Counter.Provider>
</Counter.Provider>
);
}
render(<App />, document.getElementById("root"));
API
createContainer(useHook)
import { createContainer } from "unstated-fast";
function useCustomHook() {
let [value, setValue] = useState();
let onChange = (e) => setValue(e.currentTarget.value);
return { value, onChange };
}
let Container = createContainer(useCustomHook);
// Container === { Provider, useContainer }
<Container.Provider>
function ParentComponent() {
return (
<Container.Provider>
<ChildComponent />
</Container.Provider>
);
}
<Container.Provider initialState>
function useCustomHook(initialState = "") {
let [value, setValue] = useState(initialState);
// ...
}
function ParentComponent() {
return (
<Container.Provider initialState={"value"}>
<ChildComponent />
</Container.Provider>
);
}
Container.useContainer()
function ChildComponent() {
let input = Container.useContainer();
return <input value={input.value} onChange={input.onChange} />;
}
function ChildComponent() {
let value = Container.useContainer((state) => state.value);
return <input value={input.value} />;
}