UNPKG

@runicjs/runic-react

Version:

Tools for working with Runic in React

108 lines (86 loc) 2.68 kB
# Runic Runic React provides tools for working with Runic in React. > **Warning** > Runic React is in its infancy. It's not safe to use in production at this time. ## Roadmap - [x] Implement `useStore` - [x] Publish a proper build to NPM (https://www.npmjs.com/package/@runicjs/runic-react) - [x] Write tests - [x] Implement `useStores` - [ ] Test selector that relies on a value from another selector that just changed - [ ] Test default selector (entire state) - [ ] Test creating stores dynamically (e.g. in a Context) and destroying them - [ ] Implement TodoMVC using runic-react - [ ] Verify that there are no unnecessary rerenders - [ ] Implement a larger app with more complex state using runic. RealWorld perhaps? ## Usage ### `useStore` ```tsx import { createStore } from '@runicjs/runic'; import { useStore } from '@runicjs/runic-react'; type Counter = { count: number; }; export const counterStore = createStore<Counter>({ count: 0, }); export const increment = () => { updateState(counterStore, (counter) => { counter.count++; }); }; export const decrement = () => { updateState(counterStore, (counter) => { counter.count--; }); }; function Counter() { // Only re-renders when count changes const count = useStore(counterStore, (counter) => counter.count); // "Computed" value const doubled = useStore(counterStore, (counter) => counter.count * 2); return ( <div> <div> {count} * 2 = {doubled} </div> <button onClick={decrement}>-</button> <button onClick={increment}>+</button> </div> ); } ``` ### `useStores` ```ts import { createStore } from '@runicjs/runic'; import { useStores } from '@runicjs/runic-react'; import deepEqual from 'fast-deep-equal'; type User = { id: number; }; const userStore = createStore<User>({ id: 1, }); type Todo = { userId: number; id: number; text: string; done: boolean }; type TodoList = { todos: Array<Todo>; }; const todoListStore = createStore<TodoList>({ todos: [ { userId: 1, id: 1, text: 'First task', done: false }, { userId: 2, id: 2, text: 'Second task', done: true }, { userId: 1, id: 3, text: 'Third task', done: false }, ], }); const UserTodos = () => { const userTodos = useStores<IncompleteTodos>( // Listen for changes to any store that is passed in. [userStore, todoListStore], ([user, todoList]) => { return todoList.todos.filter((todo) => todo.userId === user.id); }, // Gives you control over whether to rerender after the selector runs. deepEqual, ); }; ```