forked from pmndrs/jotai
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
docs(advanced-recipes): initialize atom on render (pmndrs#1293)
* docs: initialize atom on demand * chore: include example * docs: rename on-demand to on-render * docs: typos * docs: grammar * docs: move to guides * chore: remove advanced-guides
- Loading branch information
1 parent
09fad0a
commit 466499d
Showing
1 changed file
with
87 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
--- | ||
title: Initializing Atom State on Render | ||
description: How to initialize atom state on initial render | ||
nav: 3.12 | ||
--- | ||
|
||
There are times when you need to create an reusable component which uses atoms. | ||
|
||
These atoms' initial state are determined by the props passed to the component. | ||
|
||
Below is a basic example of illustrating how you can use `Provider` and its prop, `initialValues`, to initialize state. | ||
|
||
### Basic Example | ||
|
||
> CodeSandbox link: [codesandbox](https://codesandbox.io/s/strange-tdd-gb1eo0?file=/src/App.js). | ||
Consider a basic example where you have a reusable `TextDisplay` component that allows you to display and update plain text. | ||
|
||
This component has two child components, `PrettyText` and `UpdateTextInput`. | ||
|
||
- `PrettyText` displays the text in blue. | ||
- `UpdateTextInput` is an input field which updates the text value. | ||
|
||
As opposed to passing `text` as a prop in the two child components, you decided that the `text` state should be shared between components as an atom. | ||
|
||
To make `TextDisplay` component reusable, we take in a prop `initialTextValue`, which determines the initial state of the `text` atom. | ||
|
||
To tie `initialTextValue` to `textAtom`, we wrap the child components in a `Provider`. Then, we populate the `initialValues` array of atom tuples with the initial values. | ||
|
||
```jsx | ||
const textAtom = atom('') | ||
|
||
const PrettyText = () => { | ||
const [text] = useAtom(textAtom) | ||
return ( | ||
<> | ||
<text | ||
style={{ | ||
color: 'blue', | ||
}}> | ||
{text} | ||
</text> | ||
</> | ||
) | ||
} | ||
|
||
const UpdateTextInput = () => { | ||
const [text, setText] = useAtom(textAtom) | ||
const handleInputChange = (e) => { | ||
setText(e.target.value) | ||
} | ||
return ( | ||
<> | ||
<input onChange={handleInputChange} value={text} /> | ||
</> | ||
) | ||
} | ||
|
||
export const TextDisplay = ({ initialTextValue }) => { | ||
return ( | ||
// initialising on state with prop on render here | ||
<Provider initialValues={[[textAtom, initialTextValue]]}> | ||
<PrettyText /> | ||
<br /> | ||
<UpdateTextInput /> | ||
</Provider> | ||
) | ||
} | ||
``` | ||
|
||
Now, we can easily resue `TextDisplay` component with different initial text values despite them referencing the "same" atom. | ||
|
||
```jsx | ||
export default function App() { | ||
return ( | ||
<div className="App"> | ||
<TextDisplay initialTextValue="initial text value 1" /> | ||
|
||
<TextDisplay initialTextValue="initial text value 2" /> | ||
</div> | ||
) | ||
} | ||
``` | ||
|
||
This behavior is due to our child components looking for the lowest commmon `Provider` ancestor to derive its value. | ||
|
||
For more information on `Provider` behavior, please read the docs [here](https://jotai.org/docs/api/core#provider). |