### 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 (
); }
```
--------------------------------
### 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: [],
});
```