RecoilJS is a state lib that promotes a data-flow graph.
I built out a set of examples comparing Recoil to regular React
You need a RecoilRoot
import React from 'react';import {RecoilRoot,atom,selector,useRecoilState,useRecoilValue,} from 'recoil';function App() {return (<RecoilRoot><CharacterCounter /></RecoilRoot>);}
Atoms are built using a function and are the fundamental unit of recoil
const textState = atom({key: 'textState', // unique ID (with respect to other atoms/selectors)default: '', // default value (aka initial value)});
useRecoilState
functions similarly to useState
const [text, setText] = useRecoilState(textState);
There is a corresponding hook for if you want to "only read": useRecoilValue
.
const count = useRecoilValue(charCountState);
Selectors take atoms as arguments. If you use a selector and get
another value in the getter of that selector you'll see a setState warning that won't currently affect program operation.
const charCountState = selector({key: 'charCountState', // unique ID (with respect to other atoms/selectors)get: ({get}) => {const text = get(textState);return text.length;},});
useRecoilCallback
seems like a way to call async functions from render based on props? It can get an async atom value as a promise.
useRecoilStateLoadable
is a big ? feels. Something to do with Suspense ish.
{state: ?,getValue() {},toPromise() {}}
this hook will not throw a Promise when reading from a pending asynchronous selector (for the purpose of working alongside Suspense)
import {atom, selector, useRecoilState} from 'recoil';const tempFahrenheit = atom({key: 'tempFahrenheit',default: 32,});const tempCelcius = selector({key: 'tempCelcius',get: ({get}) => ((get(temptempFahrenheit) - 32) * 5) / 9,set: ({set}, newValue) => set(tempFahrenheit, (newValue * 9) / 5 + 32),});function TempCelcius() {const [tempF, setTempF] = useRecoilState(tempFahrenheit);const [tempC, setTempC] = useRecoilState(tempCelcius);const addTenCelcius = () => setTempC(tempC + 10);const addTenFahrenheit = () => setTempF(tempF + 10);return (<div>Temp (Celcius): {tempC}<br />Temp (Fahrenheit): {tempF}<br /><button onClick={addTenCelcius}>Add 10 Celcius</button><br /><button onClick={addTenFahrenheit}>Add 10 Fahrenheit</button></div>);}