### RecoilRoot Component Setup Source: https://recoiljs.org/docs/introduction/getting-started Example of setting up the RecoilRoot component in a React application. RecoilRoot is necessary for any components that will use Recoil state. ```javascript import React from 'react'; import { RecoilRoot, atom, selector, useRecoilState, useRecoilValue, } from 'recoil'; function App() { return ( ); } ``` -------------------------------- ### RecoilURLSyncTransit Example Implementation Source: https://recoiljs.org/docs/recoil-sync/api/RecoilURLSyncTransit An example demonstrating the usage of RecoilURLSyncTransit with a custom ViewState class, including defining handlers and integrating with Recoil atoms and effects. ```javascript class ViewState { active: boolean; pos: [number, number]; constructor(active: boolean, pos: [number, number]) { this.active = active; this.pos = pos; } // ... } const viewStateChecker = custom((x) => (x instanceof ViewState ? x : null)); const HANDLERS = [ { tag: 'VS', class: ViewState, write: (x) => [x.active, x.pos], read: ([active, pos]) => new ViewState(active, pos), }, ]; function MyApp() { return ( {/* children */} ); } const ViewState = atom({ key: 'ViewState', default: new ViewState(true, [1, 2]), effects: [syncEffect({storeKey: 'transit-url', refine: viewStateChecker})], }); ``` -------------------------------- ### Simple Example Source: https://recoiljs.org/docs/recoil-relay/api/graphQLSelector Demonstrates a basic usage of graphQLSelector with static variables. ```APIDOC ## POST /api/users ### Description Creates a user account. ### Method POST ### Endpoint `/api/users` ### Parameters #### Request Body - **username** (string) - Required - The desired username. - **email** (string) - Required - The user's email address. - **password** (string) - Required - The user's password. ### Request Example ```json { "username": "johndoe", "email": "john.doe@example.com", "password": "securepassword123" } ``` ### Response #### Success Response (201) - **id** (string) - The unique identifier for the newly created user. - **username** (string) - The username of the created user. - **email** (string) - The email address of the created user. #### Response Example ```json { "id": "user-12345", "username": "johndoe", "email": "john.doe@example.com" } ``` ``` -------------------------------- ### Basic Selector Family Example Source: https://recoiljs.org/docs/api-reference/utils/selectorFamily Demonstrates how to create and use a basic selector family to derive state based on a multiplier. ```APIDOC ## Example ```javascript const myNumberState = atom({ key: 'MyNumber', default: 2, }); const myMultipliedState = selectorFamily({ key: 'MyMultipliedNumber', get: (multiplier) => ({get}) => { return get(myNumberState) * multiplier; }, // optional set set: (multiplier) => ({set}, newValue) => { set(myNumberState, newValue / multiplier); }, }); function MyComponent() { // defaults to 2 const number = useRecoilValue(myNumberState); // defaults to 200 const multipliedNumber = useRecoilValue(myMultipliedState(100)); return
...
; } ``` ### Description This example shows a `selectorFamily` named `myMultipliedState` that takes a `multiplier` as a parameter. It multiplies the value of `myNumberState` by this multiplier. The `useRecoilValue` hook is used to access the derived state, passing the parameter to the `selectorFamily`. ``` -------------------------------- ### Setup RecoilRelayEnvironment with EnvironmentKey Source: https://recoiljs.org/docs/recoil-relay/graphql-queries Registers an EnvironmentKey for preloaded queries and sets up the RecoilRelayEnvironment at the application root. This is a prerequisite for preloading GraphQL queries. ```javascript export const preloadedEnvironmentKey = new EnvironmentKey('preloaded'); export function AppRoot() { const preloadedEnvironment = useRelayEnvironment(); return ( {/* My App */} ) } ``` -------------------------------- ### Example: Reading and Mapping Snapshot State (React) Source: https://recoiljs.org/docs/api-reference/core/Snapshot Demonstrates how to use `useRecoilCallback` to access a snapshot, read atom state using `getLoadable`, and create a new snapshot with modified state using `snapshot.map`. This example shows a common pattern for inspecting and transforming Recoil state within a React component. ```javascript function MyComponent() { const logState = useRecoilCallback(({snapshot}) => () => { console.log("State: ", snapshot.getLoadable(myAtom).contents); const newSnapshot = snapshot.map(({set}) => set(myAtom, 42)); }); } ``` -------------------------------- ### Install Recoil Nightly Builds Source: https://recoiljs.org/docs/introduction/installation Installs the latest daily build of Recoil directly from the GitHub repository's main branch. This is useful for testing the newest features or bug fixes before they are officially released. ```bash npm install https://github.com/facebookexperimental/Recoil.git#nightly ``` ```bash yarn add https://github.com/facebookexperimental/Recoil.git#nightly ``` ```json "recoil": "facebookexperimental/Recoil.git#nightly" ``` -------------------------------- ### Synchronous Temperature Conversion Example Source: https://recoiljs.org/docs/api-reference/core/selector A full example of a bi-directional selector used to convert between Fahrenheit and Celsius, including a React component for interaction. ```javascript import {atom, selector, useRecoilState, DefaultValue, useResetRecoilState} from 'recoil'; const tempFahrenheit = atom({ key: 'tempFahrenheit', default: 32, }); const tempCelsius = selector({ key: 'tempCelsius', get: ({get}) => ((get(tempFahrenheit) - 32) * 5) / 9, set: ({set}, newValue) => set(tempFahrenheit, newValue instanceof DefaultValue ? newValue : (newValue * 9) / 5 + 32), }); function TempCelsius() { const [tempF, setTempF] = useRecoilState(tempFahrenheit); const [tempC, setTempC] = useRecoilState(tempCelsius); const resetTemp = useResetRecoilState(tempCelsius); return (
Temp (Celsius): {tempC}
Temp (Fahrenheit): {tempF}


); } ``` -------------------------------- ### Using Recoil GraphQL Selectors with Relay Source: https://recoiljs.org/docs/recoil-relay/api/RecoilRelayEnvironmentProvider Example demonstrating how to define and use a Recoil GraphQL selector with a Relay environment. ```APIDOC ## Using Recoil GraphQL Selectors with Relay ### Description This example shows how to define a `graphQLSelector` that uses a specific Relay environment and how to consume its data within a React component using `useRecoilValue`. ### Method N/A (This is a conceptual example of Recoil and Relay integration) ### Endpoint N/A ### Parameters N/A ### Request Example ```javascript const myQuery = graphQLSelector({ key: 'MyQuery', environment: myEnvironmentKey, // Assumes myEnvironmentKey is defined and passed to RecoilRelayEnvironmentProvider query: graphql`...`, // Your GraphQL query string variables: {}, }); function MyComponent() { const results = useRecoilValue(myQuery); // Use the results data here } ``` ### Response #### Success Response (200) - **results** (any) - The data returned by the GraphQL query. #### Response Example ```json { "data": { ... } // Structure depends on your GraphQL query } ``` ``` -------------------------------- ### Implement GraphQL subscription in a Recoil atom Source: https://recoiljs.org/docs/recoil-relay/api/graphQLSubscriptionEffect This example demonstrates how to integrate the graphQLSubscriptionEffect into a Recoil atom definition. It shows the configuration of the environment, the subscription query, and the variables required to establish the real-time connection. ```javascript const myAtom = atom({ key: 'MyQuery', effects: [ graphQLSubscriptionEffect({ environment: myEnvironment, query: graphql` subscription MyEventSubscription($id: ID!) { myevent(id: $id) { id name } } `, variables: {id: 123}, }), ], }); ``` -------------------------------- ### Create EnvironmentKey Instance - JavaScript Source: https://recoiljs.org/docs/recoil-relay/api/EnvironmentKey Demonstrates how to create an instance of the EnvironmentKey class. This key is used to associate a specific Relay Environment with components in your Recoil setup. No external dependencies are required beyond Recoil and Relay. ```javascript const myEnvironmentKey = new EnvironmentKey('My Environment'); ``` -------------------------------- ### Install Recoil using NPM Source: https://recoiljs.org/docs/introduction/installation Installs the latest stable version of the Recoil package using the Node Package Manager (NPM). This is the standard method for most JavaScript projects. ```bash npm install recoil ``` -------------------------------- ### Install Recoil Package Source: https://recoiljs.org/docs/introduction/getting-started Commands to install the Recoil package using different package managers. This makes the Recoil library available for use in your React project. ```bash npm install recoil ``` ```bash yarn add recoil ``` ```bash bower install --save recoil ``` -------------------------------- ### Lazy Read Example with useRecoilCallback Source: https://recoiljs.org/docs/api-reference/core/useRecoilCallback Demonstrates how to use useRecoilCallback to lazily read Recoil state without subscribing the component to re-renders. The example shows logging the number of items in a cart by accessing the 'itemsInCart' atom via a snapshot. ```javascript import {atom, useRecoilCallback} from 'recoil'; const itemsInCart = atom({ key: 'itemsInCart', default: 0, }); function CartInfoDebug() { const logCartItems = useRecoilCallback(({snapshot}) => async () => { const numItemsInCart = await snapshot.getPromise(itemsInCart); console.log('Items in cart: ', numItemsInCart); }, []); return (
); } ``` -------------------------------- ### Asynchronous Data Fetching Example Source: https://recoiljs.org/docs/api-reference/core/selector Demonstrates using a selector to fetch data from an API and displaying it within a React component using Suspense. ```javascript import {selector, useRecoilValue} from 'recoil'; const myQuery = selector({ key: 'MyDBQuery', get: async () => { const response = await fetch(getMyRequestUrl()); return response.json(); }, }); function QueryResults() { const queryResults = useRecoilValue(myQuery); return (
{queryResults.foo}
); } function ResultsSection() { return ( Loading...}> ); } ``` -------------------------------- ### Create React App Source: https://recoiljs.org/docs/introduction/getting-started Boilerplate command to create a new React application using Create React App. This is the recommended way to start a new project that will use Recoil. ```bash npx create-react-app my-app ``` -------------------------------- ### Incremental Loading with waitForNone Source: https://recoiljs.org/docs/api-reference/utils/waitForNone This example demonstrates how to use waitForNone to render a chart with multiple layers. It maps over the returned Loadables to display content, error messages, or spinners based on the state of each individual query. ```javascript function MyChart({layerQueries}: {layerQueries: Array>}) { const layerLoadables = useRecoilValue(waitForNone(layerQueries)); return ( {layerLoadables.map((layerLoadable, i) => { switch (layerLoadable.state) { case 'hasValue': return ; case 'hasError': return ; case 'loading': return ; } })} ); } ``` -------------------------------- ### Pre-fetching Data with useRecoilCallback Source: https://recoiljs.org/docs/guides/asynchronous-data-queries Initiate data fetching before rendering by using useRecoilCallback to trigger a selector query. This improves performance by starting the network request as soon as a user interaction occurs. ```javascript function CurrentUserInfo() { const currentUser = useRecoilValue(currentUserInfoQuery); const friends = useRecoilValue(friendsInfoQuery); const changeUser = useRecoilCallback(({snapshot, set}) => userID => { snapshot.getLoadable(userInfoQuery(userID)); // pre-fetch user info set(currentUserIDState, userID); // change current user to start new render }); return (

{currentUser.name}

    {friends.map(friend =>
  • changeUser(friend.id)}> {friend.name}
  • )}
); } ``` -------------------------------- ### Composing Checkers Example Source: https://recoiljs.org/docs/refine/api/Checkers Demonstrates how to compose complex checkers from basic primitives using functions like `object`, `string`, `nullable`, `array`, and `lazy`. ```APIDOC ## Composing Checkers ### Description Refine allows building complex checkers by composing simpler ones. This example shows how to define a `PersonType` checker using built-in primitives. ### Example ```typescript // type PersonType = $ReadOnly<{name: string, friends: ?Array}> // const Person: Checker const Person = object({ name: string(), friends: nullable(array(lazy(() => Person))) }); ``` ### Explanation - `object({...})`: Defines a checker for an object. - `name: string()`: Specifies that the `name` property must be a string. - `friends: nullable(array(lazy(() => Person)))`: Specifies that the `friends` property is optional (`nullable`), and if present, it must be an array (`array`) of `Person` types (`lazy(() => Person)` is used for recursive type definitions). ``` -------------------------------- ### Lazy Read Example Source: https://recoiljs.org/docs/api-reference/core/useRecoilCallback Demonstrates how to use useRecoilCallback to lazily read state without causing component re-renders. ```APIDOC ## Lazy Read Example This example uses **`useRecoilCallback()`** to lazily read state without subscribing a component to re-render when the state changes. ### Code ```javascript import {atom, useRecoilCallback} from 'recoil'; const itemsInCart = atom({ key: 'itemsInCart', default: 0, }); function CartInfoDebug() { const logCartItems = useRecoilCallback(({snapshot}) => async () => { const numItemsInCart = await snapshot.getPromise(itemsInCart); console.log('Items in cart: ', numItemsInCart); }, []); return (
); } ``` ``` -------------------------------- ### Implementing React 18 Transitions with Recoil Source: https://recoiljs.org/docs/guides/transitions This example demonstrates how to use the experimental transition-supported Recoil hooks alongside React's useTransition hook. It shows how to display a loading indicator while updating external state via a selector. ```javascript function QueryResults() { const queryParams = useRecoilValue_TRANSITION_SUPPORT_UNSTABLE(queryParamsAtom); const results = useRecoilValue_TRANSITION_SUPPORT_UNSTABLE(myQuerySelector(queryParams)); return results; } function MyApp() { const [queryParams, setQueryParams] = useRecoilState_TRANSITION_SUPPORT_UNSTABLE(queryParamsAtom); const [inTransition, startTransition] = useTransition(); return (
{inTransition ?
[Loading new results...]
: null} Results:
); } ``` -------------------------------- ### Implement Parameterized Queries with selectorFamily Source: https://recoiljs.org/docs/guides/asynchronous-data-queries Demonstrates how to use selectorFamily to create queries that accept external parameters, such as component props. It includes a complete example of integrating the selector with React components and Suspense for loading states. ```javascript const userNameQuery = selectorFamily({ key: 'UserName', get: userID => async () => { const response = await myDBQuery({userID}); if (response.error) { throw response.error; } return response.name; }, }); function UserInfo({userID}) { const userName = useRecoilValue(userNameQuery(userID)); return
{userName}
; } function MyApp() { return ( Loading...}> ); } ``` -------------------------------- ### Custom Serialization Callbacks Source: https://recoiljs.org/docs/recoil-sync/api/RecoilURLSync Example of using JSON stringify and parse for custom serialization. These should be memoized to ensure performance efficiency during re-renders. ```javascript serialize: x => JSON.stringify(x), deserialize: x => JSON.parse(x) ``` -------------------------------- ### Initialize Atoms from React Props with RecoilSync Source: https://recoiljs.org/docs/recoil-sync/implement-store This example demonstrates how to use `` to initialize Recoil atoms based on React component props. The `read` callback is configured to access prop values directly, allowing for straightforward data synchronization from the component's props into the Recoil state. ```javascript function InitFromProps({children, ...props}) { return ( props[itemKey]} > {children} ); } ``` -------------------------------- ### Example: Retaining a Snapshot for Asynchronous Use (Testing) Source: https://recoiljs.org/docs/api-reference/core/Snapshot Illustrates how to use `snapshot_UNSTABLE` to create a snapshot and then explicitly `retain()` it for asynchronous operations in a testing environment. The `releaseSnapshot()` function must be called in a `finally` block to prevent memory leaks. ```javascript test('My Test', async () => { const testSnapshot = snapshot_UNSTABLE(); const releaseSnapshot = testSnapshot.retain(); try { await something; ... use testSnapshot ... } finally { releaseSnapshot(); } }); ``` -------------------------------- ### Using GraphQL Selectors with a Registered Relay Environment Source: https://recoiljs.org/docs/recoil-relay/api/RecoilRelayEnvironment This example shows how to define and use a GraphQL selector with Recoil, referencing the environmentKey that was registered using RecoilRelayEnvironment. It illustrates fetching data using a GraphQL query and accessing it within a React component via useRecoilValue. ```javascript const myQuery = graphQLSelector({ key: 'MyQuery', environment: myEnvironmentKey, query: graphql`...`, variables: {}, }); function MyComponent() { const results = useRecoilValue(myQuery); } ``` -------------------------------- ### Perform State Transaction with useGotoRecoilSnapshot Source: https://recoiljs.org/docs/api-reference/core/useGotoRecoilSnapshot This example demonstrates how to use useGotoRecoilSnapshot to perform a batch update of multiple atoms. It captures the current state via useRecoilSnapshot, modifies it using the map method, and applies the changes when the button is clicked. ```javascript function TransactionButton(): React.Node { const snapshot = useRecoilSnapshot(); const modifiedSnapshot = snapshot.map(({set}) => { set(atomA, x => x + 1); set(atomB, x => x * 2); }); const gotoSnapshot = useGotoRecoilSnapshot(); return ; } ``` -------------------------------- ### Using noWait in a Recoil Selector Source: https://recoiljs.org/docs/api-reference/utils/noWait This example demonstrates how to use noWait within a selector's get function to handle different Loadable states such as hasValue, hasError, and loading. It allows for graceful handling of asynchronous data dependencies. ```typescript const myQuery = selector({ key: 'MyQuery', get: ({get}) => { const loadable = get(noWait(dbQuerySelector)); return { hasValue: {data: loadable.contents}, hasError: {error: loadable.contents}, loading: {data: 'placeholder while loading'}, }[loadable.state]; } }) ``` -------------------------------- ### Synchronize atom state with remote storage Source: https://recoiljs.org/docs/guides/atom-effects Demonstrates how to initialize an atom from a remote source and subscribe to external changes, ensuring the atom stays in sync with the external data store. ```javascript const syncStorageEffect = userID => ({setSelf, trigger}) => { if (trigger === 'get') { setSelf(myRemoteStorage.get(userID)); } myRemoteStorage.onChange(userID, userInfo => { setSelf(userInfo); }); return () => { myRemoteStorage.onChange(userID, null); }; }; ``` -------------------------------- ### Recoil Loadable State Handling in React Component Source: https://recoiljs.org/docs/api-reference/core/Loadable This example demonstrates how to use `useRecoilValueLoadable` to get a Loadable object in a React component and handle its different states (hasValue, loading, hasError). It conditionally renders content based on the state and throws an error if the state is 'hasError'. ```javascript function UserInfo({userID}) { const userNameLoadable = useRecoilValueLoadable(userNameQuery(userID)); switch (userNameLoadable.state) { case 'hasValue': return
{userNameLoadable.contents}
; case 'loading': return
Loading...
; case 'hasError': throw userNameLoadable.contents; } } ``` -------------------------------- ### Abstracting Stores with RecoilSync Source: https://recoiljs.org/docs/recoil-sync/sync-effect Shows how to use the same atom across different environments by swapping the sync provider. A standalone app might sync with the URL, while another uses local storage. ```typescript const currentUserState = atom({ key: 'CurrentUser', default: 0, effects: [ syncEffect({ storeKey: 'ui_state', refine: number() }), ], }); function MyStandaloneApp() { return ( ... ); } function AnotherApp() { return ( ... ) } ``` -------------------------------- ### Install Recoil using Yarn Source: https://recoiljs.org/docs/introduction/installation Installs the latest stable version of the Recoil package using the Yarn package manager. This is an alternative to NPM for managing project dependencies. ```bash yarn add recoil ``` -------------------------------- ### Using waitForAll in Recoil Selectors (Array Dependencies) Source: https://recoiljs.org/docs/api-reference/utils/waitForAll Illustrates how to use waitForAll with an array of dependencies within a Recoil selector, fetching user information for a list of friends. ```APIDOC ## Using waitForAll in Recoil Selectors (Array Dependencies) ### Description This example demonstrates using `waitForAll` with an array of dependencies inside a Recoil selector. It fetches the current user's info, then maps over their friend list to fetch each friend's info concurrently. ### Method N/A (Recoil Selector) ### Endpoint N/A ### Parameters None ### Request Example ```javascript const friendsInfoQuery = selector({ key: 'FriendsInfoQuery', get: ({get}) => { const {friendList} = get(currentUserInfoQuery); const friends = get(waitForAll( friendList.map(friendID => userInfoQuery(friendID)) )); return friends; }, }); ``` ### Response #### Success Response (200) N/A (Selector returns the fetched friends data) #### Response Example None ``` -------------------------------- ### Install Recoil using Bower Source: https://recoiljs.org/docs/introduction/installation Installs the Recoil package using the Bower package manager. This method is less common for modern front-end development but may be used in older projects. ```bash bower install --save recoil ``` -------------------------------- ### Using waitForAll in Recoil Selectors (Object Dependencies) Source: https://recoiljs.org/docs/api-reference/utils/waitForAll Shows how to use waitForAll with named dependencies in an object within a Recoil selector, fetching customer info, invoices, and payments concurrently. ```APIDOC ## Using waitForAll in Recoil Selectors (Object Dependencies) ### Description This example showcases using `waitForAll` with named dependencies provided as an object within a `selectorFamily`. It concurrently fetches customer information, invoices, and payments for a given customer ID. ### Method N/A (Recoil SelectorFamily) ### Endpoint N/A ### Parameters None ### Request Example ```javascript const customerInfoQuery = selectorFamily({ key: 'CustomerInfoQuery', get: id => ({get}) => { const {info, invoices, payments} = get(waitForAll({ info: customerInfoQuery(id), invoices: invoicesQuery(id), payments: paymentsQuery(id), })); return { name: info.name, transactions: [ ...invoices, ...payments, ], }; }, }); ``` ### Response #### Success Response (200) N/A (SelectorFamily returns the structured customer data) #### Response Example None ``` -------------------------------- ### React Component Example using useRecoilRefresher_UNSTABLE Source: https://recoiljs.org/docs/api-reference/core/useRecoilRefresher An example React component demonstrating the usage of useRecoilRefresher_UNSTABLE. It fetches data from a Recoil selector and provides a button to refresh the data by calling the returned refresher function. ```javascript const myQuery = selector({ key: 'MyQuery', get: () => fetch(myQueryURL), }); function MyComponent() { const data = useRecoilValue(myQuery); const refresh = useRecoilRefresher_UNSTABLE(myQuery); return (
Data: {data}
); } ``` -------------------------------- ### Configuring RecoilRelayEnvironment with EnvironmentKey Source: https://recoiljs.org/docs/recoil-relay/environment Demonstrates how to create an EnvironmentKey and use the RecoilRelayEnvironment component to register a Relay environment within a RecoilRoot. This allows Recoil atoms and selectors to reference the environment via the key. ```javascript const myEnvironmentKey = new EnvironmentKey('My Environment'); function MyApp() { const myEnvironment = useMyRelayEnvironment(); return ( {/* Components here can use Recoil atoms/selectors which reference myEnvironmentKey */} ) } ``` -------------------------------- ### Recoil useSetRecoilState Example Usage Source: https://recoiljs.org/docs/api-reference/core/useSetRecoilState Demonstrates how to use the `useSetRecoilState` hook in a React component to update a Recoil atom. This example shows adding a name to a list of names stored in state, without causing the component to re-render when the list is updated. ```javascript import {atom, useSetRecoilState} from 'recoil'; import { useState } from 'react'; const namesState = atom({ key: 'namesState', default: ['Ella', 'Chris', 'Paul'], }); function FormContent({setNamesState}) { const [name, setName] = useState(''); return ( <> setName(e.target.value)} /> ) } // This component will be rendered once when mounting function Form() { const setNamesState = useSetRecoilState(namesState); return ; } ``` -------------------------------- ### Define a Basic graphQLSelector Source: https://recoiljs.org/docs/recoil-relay/api/graphQLSelector Demonstrates how to initialize a basic graphQLSelector with a static environment, query, and variables. It maps the raw GraphQL response directly to the selector value. ```javascript const eventQuery = graphQLSelector({ key: 'EventQuery', environment: myEnvironment, query: graphql` query MyEventQuery($id: ID!) { myevent(id: $id) { id name } } `, variables: {id: 123}, mapResponse: data => data, }); ``` -------------------------------- ### Backward Compatibility: Migrating Atom Storage with Multiple Effects Source: https://recoiljs.org/docs/recoil-sync/sync-effect Demonstrates migrating an atom to sync with a new external store by using multiple `syncEffect` instances, each targeting a different `storeKey`. This allows for a gradual migration process. ```javascript const myAtom = atom({ key: 'MyAtom', default: 0, effects: [ syncEffect({ storeKey: 'old_store', refine: number() }), syncEffect({ storeKey: 'new_store', refine: number() }) ] }) ``` -------------------------------- ### Configure RecoilRelayEnvironmentProvider Source: https://recoiljs.org/docs/recoil-relay/api/RecoilRelayEnvironmentProvider This snippet demonstrates how to wrap an application with the RecoilRelayEnvironmentProvider to provide a Relay environment to the component tree. It requires an instance of a Relay environment and an EnvironmentKey. ```javascript const myEnvironmentKey = new EnvironmentKey('My Environment'); function MyApp() { return ( {/** My App **/} ); } ``` -------------------------------- ### syncEffect() with Nullable and Custom Types Source: https://recoiljs.org/docs/recoil-sync/sync-effect Examples of using syncEffect() with nullable types and custom validation functions. ```APIDOC ## syncEffect() with Nullable and Custom Types ### Description Illustrates how to use `syncEffect()` with `nullable()` for optional values and a custom function for user-defined class validation. ### Method N/A (Atom Effect) ### Endpoint N/A (Atom Effect) ### Parameters #### Request Body - **refine** (Refine Checker) - Required - The Refine checker for input validation. - `nullable(number())`: Validates a number that can be null. - `custom(x => x instanceof MyClass ? x : null)`: Validates if an object is an instance of `MyClass`. ### Request Example ```javascript // Example for a nullable number syncEffect({ refine: nullable(number()), }) // Example for a custom user class syncEffect({ refine: custom(x => x instanceof MyClass ? x : null), }) ``` ### Response #### Success Response (200) N/A (Atom Effect) #### Response Example N/A (Atom Effect) ``` -------------------------------- ### Parameterized Default Values Source: https://recoiljs.org/docs/api-reference/utils/atomFamily Examples of providing dynamic default values to an atomFamily using a function or a selectorFamily. ```javascript const myAtomFamily = atomFamily({ key: 'MyAtom', default: param => defaultBasedOnParam(param), }); const mySelectorAtomFamily = atomFamily({ key: 'MyAtom', default: selectorFamily({ key: 'MyAtom/Default', get: param => ({get}) => { const otherAtomValue = get(otherState); return computeDefaultUsingParam(otherAtomValue, param); }, }), }); ``` -------------------------------- ### Queries with Parameters using selectorFamily Source: https://recoiljs.org/docs/guides/asynchronous-data-queries Demonstrates how to create queries that accept parameters, such as component props, using the `selectorFamily` helper. This allows for dynamic data fetching based on specific inputs. ```APIDOC ## Queries with Parameters Sometimes you want to be able to query based on parameters that aren't just based on derived state. For example, you may want to query based on the component props. You can do that using the **`selectorFamily()`**helper: ```javascript const userNameQuery = selectorFamily({ key: 'UserName', get: userID => async () => { const response = await myDBQuery({userID}); if (response.error) { throw response.error; } return response.name; }, }); function UserInfo({userID}) { const userName = useRecoilValue(userNameQuery(userID)); return
{userName}
; } function MyApp() { return ( Loading...}> ); } ``` ``` -------------------------------- ### Backward Compatibility: Upgrading Atom Key with Read Option Source: https://recoiljs.org/docs/recoil-sync/sync-effect Illustrates how to manage changes in an atom's key over time using the `read` option in `syncEffect()`. This allows reading from a new key while providing a fallback to an old key if the new one is not found. ```javascript const myAtom = atom({ key: 'MyAtom', default: 0, effects: [ syncEffect({ itemKey: 'new_key', read: ({read}) => read('new_key') ?? read('old_key') }) ] }) ``` -------------------------------- ### Atomic State Update Transaction Source: https://recoiljs.org/docs/api-reference/core/useRecoilTransaction Example of updating multiple atoms based on current state values within a single transaction. ```javascript const goForward = useRecoilTransaction_UNSTABLE(({get, set}) => (distance) => { const heading = get(headingState); const position = get(positionState); set(positionState, { x: position.x + cos(heading) * distance, y: position.y + sin(heading) * distance, }); }); ``` -------------------------------- ### Define Static and Dynamic Recoil Selectors Source: https://recoiljs.org/docs/api-reference/core/selector Demonstrates how to create a simple selector with a static dependency and a more complex selector that dynamically switches dependencies based on state. ```javascript const mySelector = selector({ key: 'MySelector', get: ({get}) => get(myAtom) * 100, }); const toggleState = atom({key: 'Toggle', default: false}); const mySelector = selector({ key: 'MySelector', get: ({get}) => { const toggle = get(toggleState); if (toggle) { return get(selectorA); } else { return get(selectorB); } }, }); ``` -------------------------------- ### syncEffect() with Item and Store Keys Source: https://recoiljs.org/docs/recoil-sync/sync-effect Configuring custom item keys and store keys for synchronization. ```APIDOC ## syncEffect() with Item and Store Keys ### Description This example demonstrates how to specify a custom `itemKey` and `storeKey` for `syncEffect()` to manage synchronization with specific external stores and items. ### Method N/A (Atom Effect) ### Endpoint N/A (Atom Effect) ### Parameters #### Request Body - **itemKey** (string) - Optional - A unique key for the item in the external store. Defaults to the atom's key. - **storeKey** (string) - Optional - The key of the external store to sync with. Defaults to the store defined in ``. - **refine** (Refine Checker) - Required - The Refine checker for input validation. ### Request Example ```javascript atom({ key: 'AtomKey', effects: [ syncEffect({ itemKey: 'myItem', storeKey: 'storeA', refine: string(), }), ], }); ``` ### Response #### Success Response (200) N/A (Atom Effect) #### Response Example N/A (Atom Effect) ``` -------------------------------- ### Define Synchronous Atom and Selector in Recoil Source: https://recoiljs.org/docs/guides/asynchronous-data-queries Demonstrates the basic setup of an atom to hold state and a selector to derive data synchronously from that atom. ```javascript const currentUserIDState = atom({ key: 'CurrentUserID', default: 1 }); const currentUserNameState = selector({ key: 'CurrentUserName', get: ({get}) => { return tableOfUsers[get(currentUserIDState)].name; }, }); function CurrentUserInfo() { const userName = useRecoilValue(currentUserNameState); return
{userName}
; } function MyApp() { return ( ); } ``` -------------------------------- ### Initialize Recoil Atom with Promise Source: https://recoiljs.org/docs/guides/atom-effects Demonstrates how to initialize an atom using a Promise passed to setSelf. This allows the use of React Suspense to display a fallback while the persisted value is being retrieved. ```javascript const localForageEffect = key => ({setSelf, onSet}) => { setSelf(localForage.getItem(key).then(savedValue => savedValue != null ? JSON.parse(savedValue) : new DefaultValue() // Abort initialization if no value was stored )); // Subscribe to state changes and persist them to localForage onSet((newValue, _, isReset) => { isReset ? localForage.removeItem(key) : localForage.setItem(key, JSON.stringify(newValue)); }); }; const currentUserIDState = atom({ key: 'CurrentUserID', default: 1, effects: [ localForageEffect('current_user'), ] }); ``` -------------------------------- ### Observing All State Changes Source: https://recoiljs.org/docs/guides/dev-tools Use `useRecoilSnapshot()` or `useRecoilTransactionObserver_UNSTABLE()` to subscribe to all state changes and get a snapshot of the new state. This allows inspection of modified atoms and their values. ```APIDOC ## Observing All State Changes ### Description This hook subscribes to all state changes in Recoil and provides a `Snapshot` object representing the current state. It iterates over modified nodes to log their keys and values. ### Method `useRecoilSnapshot()` ### Endpoint N/A (Hook) ### Parameters None ### Request Example ```javascript function DebugObserver() { const snapshot = useRecoilSnapshot(); useEffect(() => { console.debug('The following atoms were modified:'); for (const node of snapshot.getNodes_UNSTABLE({isModified: true})) { console.debug(node.key, snapshot.getLoadable(node)); } }, [snapshot]); return null; } function MyApp() { return ( ... ); } ``` ### Response #### Success Response (N/A - Hook returns a Snapshot) - **snapshot** (`Snapshot` object) - An immutable snapshot of the Recoil state. #### Response Example (See Request Example for usage within `DebugObserver`) ``` -------------------------------- ### Define and Use a Recoil Atom Source: https://recoiljs.org/docs/api-reference/core/atom This example demonstrates how to define a basic counter atom using the atom function and how to interact with it in a React component using the useRecoilState hook. ```javascript import {atom, useRecoilState} from 'recoil'; const counter = atom({ key: 'myCounter', default: 0, }); function Counter() { const [count, setCount] = useRecoilState(counter); const incrementByOne = () => setCount(count + 1); return (
Count: {count}
); } ``` -------------------------------- ### Recoil Configuration and State Definition Source: https://recoiljs.org/docs/introduction/getting-started This section covers the initialization of the RecoilRoot provider, the definition of atoms for base state, and selectors for derived state calculations. ```APIDOC ## Recoil Core Concepts ### Description This documentation outlines how to initialize Recoil in a React application and define state units. ### RecoilRoot Wrap your application or component tree with `RecoilRoot` to enable state management. ### Atom Definition Atoms are units of state. Components subscribing to an atom will re-render when the atom's value changes. ### Selector Definition Selectors represent derived state, computed from atoms or other selectors using a pure function. ### Implementation Example ```javascript // Define an atom const textState = atom({ key: 'textState', default: '', }); // Define a selector const charCountState = selector({ key: 'charCountState', get: ({get}) => { const text = get(textState); return text.length; }, }); // Root component function App() { return ( ); } ``` ``` -------------------------------- ### Implementing Many-to-One Atom Mappings Source: https://recoiljs.org/docs/recoil-sync/sync-effect An example of a custom sync effect that aggregates state from multiple external items into a single atom object using read and write handlers. ```typescript function manyToOneSyncEffect() { syncEffect({ refine: object({ foo: nullable(number()), bar: nullable(number()) }), read: ({read}) => ({foo: read('foo'), bar: read('bar')}), write: ({write, reset}, newValue) => { if (newValue instanceof DefaultValue) { reset('foo'); reset('bar'); } else { write('foo', newValue.foo); write('bar', newValue.bar); } }, }); } atom<{foo: number, bar: number}>({ key: 'MyObject', default: {}, effects: [manyToOneSyncEffect()], }); ``` -------------------------------- ### Compare Atom Effects with React useEffect Source: https://recoiljs.org/docs/guides/atom-effects An example of how state synchronization is typically handled using React's useEffect hook, which serves as a contrast to the more co-located Atom Effects approach. ```javascript const myState = atom({key: 'Key', default: null}); function MyStateEffect() { const [value, setValue] = useRecoilState(myState); useEffect(() => { store.set(value); store.onChange(setValue); return () => { store.onChange(null); }; }, [value]); return null; } ``` -------------------------------- ### syncEffect() Basic Usage Source: https://recoiljs.org/docs/recoil-sync/sync-effect Demonstrates the basic usage of syncEffect() with Refine for input validation. ```APIDOC ## syncEffect() Basic Usage ### Description This example shows how to use `syncEffect()` with the `refine` option to validate and synchronize a simple string atom. ### Method N/A (Atom Effect) ### Endpoint N/A (Atom Effect) ### Parameters #### Request Body - **refine** (Refine Checker) - Required - The Refine checker to validate the input from the external store. Must match the atom's type. ### Request Example ```javascript syncEffect({ refine: string(), }) ``` ### Response #### Success Response (200) N/A (Atom Effect) #### Response Example N/A (Atom Effect) ``` -------------------------------- ### Using waitForAll with Named Dependencies in a SelectorFamily Source: https://recoiljs.org/docs/api-reference/utils/waitForAll Illustrates how to resolve multiple named asynchronous dependencies concurrently within a selectorFamily using an object structure. ```javascript const customerInfoQuery = selectorFamily({ key: 'CustomerInfoQuery', get: id => ({get}) => { const {info, invoices, payments} = get(waitForAll({ info: customerInfoQuery(id), invoices: invoicesQuery(id), payments: paymentsQuery(id), })); return { name: info.name, transactions: [ ...invoices, ...payments, ], }; }, }); ``` -------------------------------- ### syncEffect() with Complex Refine Object Validation Source: https://recoiljs.org/docs/recoil-sync/sync-effect Provides an example of `syncEffect()` using a complex validation schema with Refine's `object()`, `number()`, `array()`, `dict()`, and `tuple()` for nested data structures. ```javascript syncEffect({ refine: object({ id: number(), friends: array(number()), positions: dict(tuple(bool(), number())) }) }) ``` -------------------------------- ### Initialize Recoil State with RecoilRoot Source: https://recoiljs.org/docs/api-reference/core/Snapshot Demonstrates how to initialize Recoil state synchronously using the `initializeState` prop of the `` component. This is particularly useful for server-side rendering or loading persisted state when all atoms are known in advance. ```javascript function MyApp() { function initializeState({set}) { set(myAtom, 'foo'); } return ( ... ); } ``` -------------------------------- ### Transform GraphQL Responses in a Selector Source: https://recoiljs.org/docs/recoil-relay/api/graphQLSelector Illustrates how to use mapResponse to transform server data before it is stored in the selector. This example includes both simple data extraction and complex transformation involving other Recoil state. ```javascript const eventNameQuery = graphQLSelector({ key: 'EventNameQuery', environment: myEnvironment, query: graphql` query MyEventQuery($id: ID!) { myevent(id: $id) { id name } } `, variables: ({get}) => ({id: get(currentIDAtom)}), mapResponse: (data, {get}) => get(prefixAtom) + ':' + data.myevent?.name, }); ``` -------------------------------- ### Implementing Normalized State with Recoil Atoms Source: https://recoiljs.org/docs/basic-tutorial/performance Demonstrates how to split the Recoil state for a todo list into two parts: an array of todo item IDs and a mapping of item ID to item data. This approach, using a standard atom for the IDs and potentially atomFamily for the item data, facilitates more efficient updates and prevents re-rendering of the entire list when individual items change. ```javascript const todoListItemIdsState = atom({ key: 'todoListItemIdsState', default: [], }); ```