--- title: Initializing state on render description: How to initialize atom state on initial render nav: 8.13 --- 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 illustrating how you can use `Provider` and its prop, `initialValues`, to initialize state. ### Basic Example > CodeSandbox link: [codesandbox](https://codesandbox.io/s/init-atoms-with-usehydrateatoms-nryk1w). 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 component where we create a new store and pass it to a `Provider` component. ```jsx const textAtom = atom('') const PrettyText = () => { const [text] = useAtom(textAtom) return ( <> {text} ) } const UpdateTextInput = () => { const [text, setText] = useAtom(textAtom) const handleInputChange = (e) => { setText(e.target.value) } return ( <> ) } const HydrateAtoms = ({ initialValues, children }) => { // initialising on state with prop on render here useHydrateAtoms(initialValues) return children } export const TextDisplay = ({ initialTextValue }) => (
) ``` Now, we can easily reuse `TextDisplay` component with different initial text values despite them referencing the "same" atom. ```jsx export default function App() { return (
) } ``` This behavior is due to our child components looking for the lowest common `Provider` ancestor to derive its value. For more information on `Provider` behavior, please read the docs [here](../core/provider.mdx). For more complex use cases, check out [Scope extension](../extensions/scope.mdx). ### Using Typescript `useHydrateAtoms` has overloaded types and typescript cannot extract types from overloaded function. It is recommended to use a `Map` when passing initial atom values to the `useHydrateAtoms`. Here is a working example: ```tsx import type { ReactNode } from 'react' import { Provider, atom, useAtomValue } from 'jotai' import type { WritableAtom } from 'jotai' import { useHydrateAtoms } from 'jotai/utils' const testAtom = atom('') export default function App() { return ( ) } //This component contains all the states and the logic function Component() { const testAtomValue = useAtomValue(testAtom) return
{testAtomValue}
} function AtomsHydrator({ atomValues, children, }: { // eslint-disable-next-line @typescript-eslint/no-explicit-any atomValues: Iterable< readonly [WritableAtom, unknown] > children: ReactNode }) { useHydrateAtoms(new Map(atomValues)) return children } ```