{
    "version": "https://jsonfeed.org/version/1",
    "title": "Recoil Blog",
    "home_page_url": "https://recoiljs.org/blog",
    "description": "Recoil Blog",
    "items": [
        {
            "id": "/2023/03/01/recoil-0.7.7-release",
            "content_html": "<ul><li>Fix potential unhandled promise rejection in <code>useRecoilCallback()</code> (<a href=\"https://github.com/facebookexperimental/Recoil/pull/2075\">#2075</a>)</li><li>Add OSS support for <a href=\"/docs/api-reference/core/RecoilEnv#recoilenv\">GateKeeper</a> feature toggling via <code>RecoilEnv.RECOIL_GKS_ENABLED</code> (<a href=\"https://github.com/facebookexperimental/Recoil/pull/2078\">#2078</a>)</li><li>Fix resolving suspense of async selectors used with SSR (<a href=\"https://github.com/facebookexperimental/Recoil/pull/2073\">#2073</a>, <a href=\"https://github.com/facebookexperimental/Recoil/pull/1960\">#1960</a>)</li><li>Fix SSR with some versions of React DOM used with Next.JS 13 (<a href=\"https://github.com/facebookexperimental/Recoil/pull/2082\">#2082</a>, <a href=\"https://github.com/facebookexperimental/Recoil/pull/2086\">#2086</a>)</li></ul>",
            "url": "https://recoiljs.org/blog/2023/03/01/recoil-0.7.7-release",
            "title": "Recoil 0.7.7",
            "summary": "- Fix potential unhandled promise rejection in useRecoilCallback() (#2075)",
            "date_modified": "2023-03-01T00:00:00.000Z"
        },
        {
            "id": "/2022/10/11/recoil-0.7.6-release",
            "content_html": "<ul><li><p>Expose flag to disable &quot;duplicate atom key&quot; checking / logging, as it was too noisy in environments such as NextJS or some dev environments using Fast Refresh. (<a href=\"https://github.com/facebookexperimental/Recoil/pull/733\">#733</a>, <a href=\"https://github.com/facebookexperimental/Recoil/pull/2020\">#2020</a>, <a href=\"https://github.com/facebookexperimental/Recoil/pull/2046\">#2046</a>)</p><ul><li>Import <a href=\"/docs/api-reference/core/RecoilEnv#recoilenv\"><code>RecoilEnv</code></a> from the recoil package, and set <code>RecoilEnv.RECOIL_DUPLICATE_ATOM_KEY_CHECKING_ENABLED = false</code> in code to disable the checking and logging.</li><li>We also support <code>process.env.RECOIL_DUPLICATE_ATOM_KEY_CHECKING_ENABLED=false</code> in NodeJS environments such as NextJs</li><li><strong><em>Caution</em></strong>: This disables all checks for duplicate atom keys including legitimate errors, so use with caution!</li></ul></li><li><p>Workaround for React 18 environments with nested renderers that don&#x27;t support <code>useSyncExternalStore()</code>. (<a href=\"https://github.com/facebookexperimental/Recoil/pull/2001\">#2001</a>, <a href=\"https://github.com/facebookexperimental/Recoil/pull/2010\">#2010</a>)</p></li></ul>",
            "url": "https://recoiljs.org/blog/2022/10/11/recoil-0.7.6-release",
            "title": "Recoil 0.7.6",
            "summary": "- Expose flag to disable \"duplicate atom key\" checking / logging, as it was too noisy in environments such as NextJS or some dev environments using Fast Refresh. (#733, #2020, #2046)",
            "date_modified": "2022-10-11T00:00:00.000Z"
        },
        {
            "id": "/2022/10/06/recoil-sync-0.2.0-release",
            "content_html": "<ul><li>Export <code>updateItems()</code> for the <a href=\"https://recoiljs.org/docs/recoil-sync/api/RecoilSync#listen-interface\"><code>listen</code></a> prop callback in <a href=\"https://recoiljs.org/docs/recoil-sync/api/RecoilSync\"><code>&lt;RecoilSync&gt;</code></a> in addition to <code>updateItem()</code> and <code>updateAllKnownItems()</code>. (<a href=\"https://github.com/facebookexperimental/Recoil/pull/2017\">#2017</a>, <a href=\"https://github.com/facebookexperimental/Recoil/pull/2035\">#2035</a>)</li><li>Removing a parameter from the URL will reset atoms when using location <code>queryParams</code> with a <code>param</code>.  This is a slight breaking change when an atom might sync with multiple URL params. (<a href=\"https://github.com/facebookexperimental/Recoil/pull/1900\">#1900</a>, <a href=\"https://github.com/facebookexperimental/Recoil/pull/1976\">#1976</a>)</li><li>Add a dev warning if an unstable <code>handlers</code> prop is detected for <a href=\"https://recoiljs.org/docs/recoil-sync/api/RecoilURLSyncTransit\"><code>&lt;RecoilURLSyncTransit&gt;</code></a>. (<a href=\"https://github.com/facebookexperimental/Recoil/pull/2044\">#2044</a>)</li></ul>",
            "url": "https://recoiljs.org/blog/2022/10/06/recoil-sync-0.2.0-release",
            "title": "Recoil Sync 0.2",
            "summary": "- Export updateItems() for the listen prop callback in ` in addition to updateItem() and updateAllKnownItems()`. (#2017, #2035)",
            "date_modified": "2022-10-06T00:00:00.000Z"
        },
        {
            "id": "/2022/08/18/refine-0.1.1-release",
            "content_html": "<ul><li>Rename <code>boolean()</code> export to <a href=\"/docs/refine/api/Primitive_Checkers#boolean\"><code>bool()</code></a> since <code>boolean</code> is a reserved word (<a href=\"https://github.com/facebookexperimental/Recoil/pull/1922\">#1922</a>, <a href=\"https://github.com/facebookexperimental/Recoil/pull/1962\">#1962</a>, <a href=\"https://github.com/facebookexperimental/Recoil/pull/1971\">#1971</a>)</li><li>Remove reference to <code>native</code> directory in <code>package.json</code> to cleanup errors for <code>react-native</code>. (<a href=\"https://github.com/facebookexperimental/Recoil/pull/1931\">#1931</a>)</li><li>Export <code>Path</code> class for custom checkers. (<a href=\"https://github.com/facebookexperimental/Recoil/pull/1950\">#1950</a>, <a href=\"https://github.com/facebookexperimental/Recoil/pull/1956\">#1956</a>)</li><li>Extend the failure message of <a href=\"/docs/refine/api/Advanced_Checkers#union\"><code>union()</code></a> and <a href=\"/docs/refine/api/Advanced_Checkers#or\"><code>or()</code></a> with each type. (<a href=\"https://github.com/facebookexperimental/Recoil/pull/1961\">#1961</a>)</li></ul>",
            "url": "https://recoiljs.org/blog/2022/08/18/refine-0.1.1-release",
            "title": "Refine 0.1.1",
            "summary": "- Rename boolean() export to bool() since boolean is a reserved word (#1922, #1962, #1971)",
            "date_modified": "2022-08-18T00:00:00.000Z"
        },
        {
            "id": "/2022/08/11/recoil-0.7.5-release",
            "content_html": "<ul><li>Fix <code>useRecoilSnapshot()</code> with React&#x27;s Fast Refresh during development (<a href=\"https://github.com/facebookexperimental/Recoil/pull/1891\">#1891</a>)</li><li>Fix <code>useRecoilSnapshot()</code> and <a href=\"https://recoiljs.org/docs/recoil-sync/introduction\"><code>recoil-sync</code></a> with changed browser behavior starting with Chrome v104 (<a href=\"https://github.com/facebookexperimental/Recoil/pull/1943\">#1943</a>, <a href=\"https://github.com/facebookexperimental/Recoil/pull/1936\">#1936</a>)</li></ul>",
            "url": "https://recoiljs.org/blog/2022/08/11/recoil-0.7.5-release",
            "title": "Recoil 0.7.5",
            "summary": "- Fix useRecoilSnapshot() with React's Fast Refresh during development (#1891)",
            "date_modified": "2022-08-11T00:00:00.000Z"
        },
        {
            "id": "/2022/06/21/recoil-sync-0.1.0-release",
            "content_html": "<p>Initial open source release for the <a href=\"https://www.npmjs.com/package/recoil-sync\"><code>recoil-sync</code></a> NPM package!  Recoil Sync provides an add-on library to help synchronize Recoil state with external systems.  Simple <a href=\"/docs/guides/asynchronous-data-queries\">asynchronous data queries</a> can be implemented via selectors or <code>useEffect()</code>, or <a href=\"/docs/guides/atom-effects\">atom effects</a> can be used for bi-directional syncing of individual atoms.  The <code>recoil-sync</code> add-on package provides some additional functionality:</p><ul><li><strong>Batching Atomic Transactions</strong> - Updates for multiple atoms can be batched together as a single transaction with the external system.  This can be important if an atomic transaction is required for consistent state of related atoms.</li><li><strong>Abstract and Flexible</strong> - This API allows users to specify what atoms to sync separately from describing the mechanism of how to sync.  This allows components to use atoms and sync with different systems in different environments without changing their implementation.  For example, a component may use atoms that persist to the URL when used in a stand-alone tool while persisting to a custom user database when embedded in another tool.</li><li><strong>Validation and Backward Compatibility</strong> - When dealing with state from external sources it is important to validate the input.  When state is persisted beyond the lifetime of an app it can also be important to consider backward compatibility of previous versions of state.  <code>recoil-sync</code> and <a href=\"/docs/refine/introduction\"><code>refine</code></a> help provide this functionality.</li><li><strong>Complex Mapping of Atoms to External Storage</strong> - There may not be a one-to-one mapping between atoms and external storage items.  Atoms may migrate to use newer versions of items, may pull props from multiple items, just a piece of some compound state, or other complex mappings.</li><li><strong>Sync with React Hooks or Props</strong> - This library enables syncing atoms with React hooks or props that are not accessible from atom effects.</li></ul><p>The <code>recoil-sync</code> library also provides built-in implementations for external stores, such as <a href=\"/docs/recoil-sync/url-persistence\">syncing with the browser URL</a>.</p><hr/><p>The basic idea is that a <a href=\"/docs/recoil-sync/sync-effect\"><code>syncEffect()</code></a> can be added to each atom that you wish to sync, and then a <a href=\"/docs/recoil-sync/api/RecoilSync\"><code>&lt;RecoilSync&gt;</code></a> is added inside your <code>&lt;RecoilRoot&gt;</code> to specify how to sync those atoms.  You can use built-in stores such as <a href=\"/docs/recoil-sync/url-persistence\"><code>&lt;RecoilURLSyncJSON&gt;</code></a>, <a href=\"/docs/recoil-sync/implement-store\">make your own</a>, or even sync different groups of atoms with different stores.</p><h2>Example</h2><h3>URL Persistence</h3><p>Here is a simple example <a href=\"/docs/recoil-sync/url-persistence\">syncing an atom with the browser URL</a>:</p><pre><code class=\"language-jsx\">const currentUserState = atom&lt;number&gt;({\n  key: &#x27;CurrentUser&#x27;,\n  default: 0,\n  effects: [\n    syncEffect({ refine: number() }),\n  ],\n});\n</code></pre><p>Then, at the root of your application, simply include <a href=\"/docs/recoil-sync/api/RecoilURLSyncJSON\"><code>&lt;RecoilURLSyncJSON&gt;</code></a> to sync all of those tagged atoms with the URL</p><pre><code class=\"language-jsx\">function MyApp() {\n  return (\n    &lt;RecoilRoot&gt;\n      &lt;RecoilURLSyncJSON location={{part: &#x27;queryParams&#x27;}}&gt;\n        ...\n      &lt;/RecoilURLSyncJSON&gt;\n    &lt;/RecoilRoot&gt;\n  )\n}\n</code></pre><p>That&#x27;s it!  Now this atom will initialize its state based on the URL during initial load, any state mutations will update the URL, and changes in the URL (such as the back button) will update the atom.  See more examples in the <a href=\"/docs/recoil-sync/sync-effect\">Sync Effect</a>, <a href=\"/docs/recoil-sync/implement-store\">Store Implementation</a>, and <a href=\"/docs/recoil-sync/url-persistence\">URL Persistence</a> guides.</p>",
            "url": "https://recoiljs.org/blog/2022/06/21/recoil-sync-0.1.0-release",
            "title": "Recoil Sync 0.1",
            "summary": "Initial open source release for the recoil-sync NPM package!  Recoil Sync provides an add-on library to help synchronize Recoil state with external systems.  Simple asynchronous data queries can be implemented via selectors or useEffect(), or atom effects can be used for bi-directional syncing of individual atoms.  The recoil-sync add-on package provides some additional functionality:",
            "date_modified": "2022-06-21T00:00:00.000Z"
        },
        {
            "id": "/2022/06/21/refine-0.1.0-release",
            "content_html": "<p>Initial open source release for the <a href=\"https://www.npmjs.com/package/@recoiljs/refine\"><code>@recoiljs/refine</code></a> library for type refinement and input validation for Flow and TypeScript!  To get started learning about Refine, check out the documentation on the core concepts of <a href=\"/docs/refine/api/Utilities\">Utilities</a> and <a href=\"/docs/refine/api/Checkers\">Checkers</a>.</p><p>The <a href=\"/docs/recoil-sync/introduction\">Recoil Sync</a> library leverages <strong>Refine</strong> for type refinement, input validation, and upgrading types for backward compatibility.  See the <a href=\"/docs/recoil-sync/introduction\"><code>recoil-sync</code> docs</a> for more details.</p><h3>Why would I want to use Refine?</h3><ul><li>Refine is useful when your code encounters <code>unknown</code> TypeScript type or <code>mixed</code> Flow type values and you need to <a href=\"/docs/refine/Introduction#type-refinement-example\">assert those values have a specific static type</a>.</li><li>Refine provides an API for building type-refinement helper functions which can validate that an unknown value conforms to an expected type.</li><li>Refine can validate input values and <a href=\"/docs/refine/Introduction#backward-compatible-example\">upgrade from previous versions</a>.</li></ul><h3>Type Refinement Example</h3><p>Coerce unknown types to a strongly typed variable.  <a href=\"/docs/refine/api/Utilities#assertion\"><code>assertion()</code></a> will throw if the input doesn&#x27;t match the expected type while <a href=\"/docs/refine/api/Utilities#coercion\"><code>coercion()</code></a> will return <code>null</code>.</p><pre><code class=\"language-jsx\">const myObjectChecker = object({\n  numberProperty: number(),\n  stringProperty: optional(string()),\n  arrayProperty: array(number()),\n});\n\nconst myObjectAssertion = assertion(myObjectChecker);\nconst myObject: CheckerReturnType&lt;myObjectChecker&gt; = myObjectAssertion({\n  numberProperty: 123,\n  stringProperty: &#x27;hello&#x27;,\n  arrayProperty: [1, 2, 3],\n});\n</code></pre><h3>Backward Compatible Example</h3><p>Using <a href=\"/docs/refine/api/Advanced_Checkers#match\"><code>match()</code></a> and <a href=\"/docs/refine/api/Advanced_Checkers#asType\"><code>asType()</code></a> you can upgrade from previous types to the latest version.</p><pre><code class=\"language-jsx\">const myChecker: Checker&lt;{str: string}&gt; = match(\n  object({str: string()}),\n  asType(string(), str =&gt; ({str: str})),\n  asType(number(), num =&gt; ({str: String(num)})),\n);\n\nconst obj1: {str: string} = coercion(myChecker({str: &#x27;hello&#x27;}));\nconst obj2: {str: string} = coercion(myChecker(&#x27;hello&#x27;));\nconst obj3: {str: string} = coercion(myChecker(123));\n</code></pre><h3>JSON Parser Example</h3><p>Refine wraps <code>JSON</code> to provide a built-in strongly typed parser.</p><pre><code class=\"language-jsx\">const myParser = jsonParser(\n    array(object({num: number()}))\n);\n\nconst result = myParser(&#x27;[{&quot;num&quot;: 1}, {&quot;num&quot;: 2}]&#x27;);\n\nif (result != null) {\n  // we can now access values in num typesafe way\n  assert(result[0].num === 1);\n} else {\n  // value failed to match parser spec\n}\n</code></pre>",
            "url": "https://recoiljs.org/blog/2022/06/21/refine-0.1.0-release",
            "title": "Refine 0.1",
            "summary": "Initial open source release for the @recoiljs/refine library for type refinement and input validation for Flow and TypeScript!  To get started learning about Refine, check out the documentation on the core concepts of Utilities and Checkers.",
            "date_modified": "2022-06-21T00:00:00.000Z"
        },
        {
            "id": "/2022/06/20/recoil-0.7.4-release",
            "content_html": "<ul><li>Fix missing flow types (<a href=\"https://github.com/facebookexperimental/Recoil/pull/1857\">#1857</a>)</li><li>Cleanup memory leak when using atoms with selector defaults. (<a href=\"https://github.com/facebookexperimental/Recoil/pull/1821\">#1821</a>, <a href=\"https://github.com/facebookexperimental/Recoil/pull/1840\">#1840</a>, <a href=\"https://github.com/facebookexperimental/Recoil/pull/1844\">#1844</a>)</li></ul>",
            "url": "https://recoiljs.org/blog/2022/06/20/recoil-0.7.4-release",
            "title": "Recoil 0.7.4",
            "summary": "- Fix missing flow types (#1857)",
            "date_modified": "2022-06-20T00:00:00.000Z"
        },
        {
            "id": "/2022/06/02/recoil-relay-0.1.0-release",
            "content_html": "<p>Initial open source release for the <a href=\"/docs/recoil-relay/introduction\"><code>recoil-relay</code></a> library for using <strong>GraphQL</strong>!</p><p>This library helps Recoil perform type safe and efficient queries using <a href=\"https://graphql.org/\">GraphQL</a> with the <a href=\"https://relay.dev\">Relay</a> library.  It provides selectors which can easily query with GraphQL.  The queries are synced with the Recoil data-flow graph so downstream selectors can derive state from them, they can depend on upstream Recoil state, and they are automatically subscribed to any changes in the graph from Relay.  Everything stays in sync automatically.</p><h3>Example</h3><p>A GraphQL query is as simple as defining a <a href=\"/docs/recoil-relay/graphql-queries\">GraphQL selector</a>:</p><pre><code class=\"language-jsx\">const userNameQuery = graphQLSelector({\n  key: &#x27;UserName&#x27;,\n  environment: myEnvironment,\n  query: graphql`\n    query UserQuery($id: ID!) {\n      user(id: $id) {\n        name\n      }\n    }\n  `,\n  variables: ({get}) =&gt; ({id: get(currentIDAtom)}),\n  mapResponse: data =&gt; data.user?.name,\n});\n</code></pre><p>Then use it like any other Recoil <a href=\"/docs/introduction/core-concepts#selectors\">selector</a>:</p><pre><code class=\"language-jsx\">function MyComponent() {\n  const userName = useRecoilValue(userNameQuery);\n  return &lt;span&gt;{userName}&lt;/span&gt;;\n}\n</code></pre>",
            "url": "https://recoiljs.org/blog/2022/06/02/recoil-relay-0.1.0-release",
            "title": "Recoil Relay 0.1",
            "summary": "Initial open source release for the recoil-relay library for using GraphQL!",
            "date_modified": "2022-06-02T00:00:00.000Z"
        },
        {
            "id": "/2022/06/01/recoil-0.7.3-release",
            "content_html": "<ul><li>Enable atoms and selectors to be used in <a href=\"/docs/api-reference/utils/selectorFamily#parameter-type\">family parameters</a> (<a href=\"https://github.com/facebookexperimental/Recoil/pull/1740\">#1740</a>)</li><li>Add <code>parentStoreID_UNSTABLE</code> to atom effects for the parent Recoil store the atom instance was cloned from.  This enables the <a href=\"/docs/recoil-relay/graphql-queries#pre-fetch-graphql\">pre-fetch pattern for GraphQL</a>.  (<a href=\"https://github.com/facebookexperimental/Recoil/pull/1744\">#1744</a>)</li><li>Atom effects can initialize or set atoms to wrapped values (<a href=\"https://github.com/facebookexperimental/Recoil/pull/1681\">#1681</a>)</li></ul>",
            "url": "https://recoiljs.org/blog/2022/06/01/recoil-0.7.3-release",
            "title": "Recoil 0.7.3",
            "summary": "- Enable atoms and selectors to be used in family parameters (#1740)",
            "date_modified": "2022-06-01T00:00:00.000Z"
        },
        {
            "id": "/2022/04/14/0.7.2-release",
            "content_html": "<p>Selector optimizations and fixes</p><h3>Optimizations and Fixes</h3><ul><li>Selector cache lookup optimizations (<a href=\"https://github.com/facebookexperimental/Recoil/pull/1720\">#1720</a>, <a href=\"https://github.com/facebookexperimental/Recoil/pull/1736\">#1736</a>)</li><li>Allow async selectors to re-evaluate when async dependencies are discovered with stale state (<a href=\"https://github.com/facebookexperimental/Recoil/pull/1736\">#1736</a>)</li></ul>",
            "url": "https://recoiljs.org/blog/2022/04/14/0.7.2-release",
            "title": "Recoil 0.7.2",
            "summary": "Selector optimizations and fixes",
            "date_modified": "2022-04-14T00:00:00.000Z"
        },
        {
            "id": "/2022/04/12/0.7.1-release",
            "content_html": "<p>Typing and various improvements</p><h3>Typing</h3><ul><li>Add explicit and required <code>children</code> prop to <code>&lt;RecoilRoot&gt;</code> and <code>useRecoilBridgeAcrossReactRoots_UNSTABLE()</code> for TypeScript to support the <a href=\"https://solverfox.dev/writing/no-implicit-children/\">removal of implicit children</a> with <a href=\"https://github.com/DefinitelyTyped/DefinitelyTyped/pull/56210\">`@types/react@^18.0.0</a> for React 18. (<a href=\"https://github.com/facebookexperimental/Recoil/pull/1718\">#1718</a>, <a href=\"https://github.com/facebookexperimental/Recoil/pull/1717\">#1717</a>, <a href=\"https://github.com/facebookexperimental/Recoil/pull/1726\">#1726</a>, <a href=\"https://github.com/facebookexperimental/Recoil/pull/1731\">#1731</a>)</li><li>Update typing for <a href=\"/docs/api-reference/utils/atomFamily#parameter-type\">family parameters</a> to better support Map, Set, and classes with <code>toJSON()</code>. (<a href=\"https://github.com/facebookexperimental/Recoil/pull/1709\">#1709</a>, <a href=\"https://github.com/facebookexperimental/Recoil/pull/1703\">#1703</a>)</li></ul><h3>Fixes</h3><ul><li>Avoid dev-mode console error with React 18 when using shared async selectors across multiple <code>&lt;RecoilRoot&gt;</code>&#x27;s. (<a href=\"https://github.com/facebookexperimental/Recoil/pull/1712\">#1712</a>)</li><li>Cleanup potential memory leak when using async selectors. (<a href=\"https://github.com/facebookexperimental/Recoil/pull/1714\">#1714</a>)</li><li>Fix potentially hung async selectors when shared across multiple roots that depend on atoms initialized with promises that don&#x27;t resolve. (<a href=\"https://github.com/facebookexperimental/Recoil/pull/1714\">#1714</a>)</li></ul>",
            "url": "https://recoiljs.org/blog/2022/04/12/0.7.1-release",
            "title": "Recoil 0.7.1",
            "summary": "Typing and various improvements",
            "date_modified": "2022-04-12T00:00:00.000Z"
        },
        {
            "id": "/2022/03/25/0.7.0-release",
            "content_html": "<p>Recoil 0.7 offers some minor API improvements, selector optimizations, and other fixes.</p><h2>New Features</h2><h3>Atom Defaults are Optional</h3><p>It is now optional to provide a default value for an atom.  If no default is provided the atom will be kept in a &quot;pending&quot; state (e.g. triggering React Suspense) until it is set. (<a href=\"https://github.com/facebookexperimental/Recoil/pull/1639\">#1639</a>)</p><p>This can help avoid awkward typing (such as unecessarily making the type nullable) or awkward placeholder values for the default.  An example minimal string atom might be:</p><pre><code class=\"language-jsx\">atom&lt;string&gt;({key: &#x27;MyString&#x27;});\n</code></pre><p>This is also useful when atoms are initialized with atom effects and a default may not be necessary:</p><pre><code class=\"language-jsx\">atom({\n  key: &#x27;MyQuery&#x27;,\n  effects: [\n    dbSyncEffect({query, variables}),\n  ],\n});\n</code></pre><h3>Other New Features</h3><ul><li>Add <code>.getStoreID()</code> method to <a href=\"/docs/api-reference/core/Snapshot\"><code>Snapshot</code></a> (<a href=\"https://github.com/facebookexperimental/Recoil/pull/1612\">#1612</a>)</li><li>Publish <code>RecoilLoadable.loading()</code> factory for making an async <a href=\"/docs/api-reference/core/Loadable\"><code>Loadable</code></a> which never resolves. (<a href=\"https://github.com/facebookexperimental/Recoil/pull/1641\">#1641</a>)</li></ul><h2>Improvements / Optimizations</h2><h3>Automatically retain snapshots for the duration of async callbacks.</h3><p>You now no longer need to manually retain snapshots for async callbacks from <a href=\"/docs/api-reference/core/useRecoilCallback\"><code>useRecoilCallback()</code></a>.  (<a href=\"https://github.com/facebookexperimental/Recoil/pull/1632\">#1632</a>)</p><pre><code class=\"language-jsx\">  const myCallback = useRecoilCallback(({snapshot}) =&gt; async () =&gt; {\n    // No longer necessary to retain() here\n    await something;\n    ... use snapshot ...\n  });\n</code></pre><p>If you want to save a Snapshot or reference it from closure state from some other scheduled handler, then you still need to <a href=\"/docs/api-reference/core/Snapshot#asynchronous-use-of-snapshots\">manually retain it</a>.</p><h3>Other Improvements / Optimizations</h3><ul><li>Optimizations for scaling with more selector dependencies.  2x improvement with 100 dependencies, 4x with 1,000, and now able to support 10,000+ dependencies. (<a href=\"https://github.com/facebookexperimental/Recoil/pull/1651\">#1651</a>, <a href=\"https://github.com/facebookexperimental/Recoil/pull/1515\">#1515</a>, <a href=\"https://github.com/facebookexperimental/Recoil/pull/914\">#914</a>)</li><li>Better error reporting when user selector implementations provide inconsistent results (<a href=\"https://github.com/facebookexperimental/Recoil/pull/1696\">#1696</a>)</li></ul><h2>Breaking Changes</h2><h3>Selector evaluation or atom defaults can use a Loadable object</h3><p>Now the selector <code>get()</code> evaluation callback or atom <code>default</code> property can use a <a href=\"/docs/api-reference/core/Loadable\"><code>Loadable</code></a> object. (<a href=\"https://github.com/facebookexperimental/Recoil/pull/1640\">#1640</a>) This can allow them to more cleanly accept synchronous error states:</p><pre><code class=\"language-jsx\">atom({\n  key: &#x27;Key&#x27;,\n  default: RecoilLoadable.error(new Error(&#x27;ERROR&#x27;)),\n});\n</code></pre><p>or mapped Loadables or placeholders:</p><pre><code class=\"language-jsx\">selector({\n  key: &#x27;Key&#x27;,\n  get: ({get}) =&gt; {\n    const queryLoadable = get(noWait(myQuerySelector));\n    if (queryLoadable.state === &#x27;loading&#x27;) {\n      return PLACEHOLDER;\n    }\n    return queryLoadable; // Pass on the query results or error state.\n  }\n})\n</code></pre><p>If you wish to explicitly evaluate a selector value to a <code>Promise</code>, <code>Loadable</code>, or <code>RecoilState</code> type object then you can now wrap them with <code>selector.value()</code> or <code>atom.value()</code>.</p><pre><code class=\"language-jsx\">selector({\n  key: &#x27;Key&#x27;,\n  get: ({get}) =&gt; {\n    // Returns an immediate synchronous value\n    return selector.value(Promise.resolve(&#x27;Promise as a value&#x27;));\n  },\n});\n</code></pre><p>This is only a minor change.  It helps make the API more consisent for handling wrappers such as <code>Promise</code> and <code>Loadable</code>, though is not yet available across the entire API.  But, it helps set the stage for future potential ability to explicitly set atoms and selectors to asynchronous values or error states.</p><h3>Other Breaking Changes</h3><ul><li><a href=\"/docs/api-reference/core/useRecoilCallback\"><code>useRecoilCallback()</code></a> now provides a snapshot for the latest state instead of the latest rendered state, which had bugs (<a href=\"https://github.com/facebookexperimental/Recoil/pull/1610\">#1610</a>, <a href=\"https://github.com/facebookexperimental/Recoil/pull/1604\">#1604</a>)</li></ul><h2>Fixes</h2><ul><li>Freezing user values in dev mode now works in JS environments without the <code>Window</code> interface. (<a href=\"https://github.com/facebookexperimental/Recoil/pull/1571\">#1571</a>)</li><li>Avoid spurious console errors from atom effects when calling <code>setSelf()</code> from <code>onSet()</code> handlers. (<a href=\"https://github.com/facebookexperimental/Recoil/pull/1589\">#1589</a>, <a href=\"https://github.com/facebookexperimental/Recoil/pull/1582\">#1582</a>)</li></ul>",
            "url": "https://recoiljs.org/blog/2022/03/25/0.7.0-release",
            "title": "Recoil 0.7",
            "summary": "Recoil 0.7 offers some minor API improvements, selector optimizations, and other fixes.",
            "date_modified": "2022-03-25T00:00:00.000Z"
        },
        {
            "id": "/2022/01/28/0.6.0-release",
            "content_html": "<p>Recoil 0.6 introduces improved support for React 18, including concurrent rendering and transitions, along with new APIs, fixes, and optimizations.</p><h2>React 18</h2><p>Recoil 0.6 uses the latest APIs from React 18 for improved safety and performance.  This release is compatible with <a href=\"https://reactjs.org/blog/2021/06/08/the-plan-for-react-18.html#whats-coming-in-react-18\">concurrent rendering</a> and <a href=\"https://reactjs.org/docs/strict-mode.html\"><code>&lt;React.StrictMode&gt;</code></a>, which is useful for testing and identifying potential issues for concurrent rendering.  Making Recoil and React state changes in the same batch now stay in sync to provided a consistent view of state.  Some of these improvements are also available while using previous versions of React.  <em>When experimenting with React 18 please use the latest RC build, as the original React <code>18.0.0-rc.0</code> package has a bug that has since been fixed.</em></p><h3>Concurrent Rendering and Transitions</h3><p>React 18 offers a new hook <a href=\"https://reactjs.org/docs/concurrent-mode-patterns.html#transitions\"><code>useTransition()</code></a> for transitioning to a new state while having control over what to render before the new state is ready.  Recoil should be compatible with this approach and provides a consistent view with React state.  However, React 18 may fallback from concurrent updates and does not yet officially support initiating transitions based on state changes to external stores.  This is something the React team is looking into supporting, but until then we have added experimental support for this through the following hooks.  This API is considered experimental because there may be use cases we haven’t found which are not handled.</p><ul><li><code>useRecoilState_TRANSITION_SUPPORT_UNSTABLE()</code></li><li><code>useRecoilValue_TRANSITION_SUPPORT_UNSTABLE()</code></li><li><code>useRecoilValueLoadable_TRANSITION_SUPPORT_UNSTABLE()</code></li></ul><p>Here&#x27;s an example that displays the current results while a new result is loading:</p><pre><code class=\"language-jsx\">function QueryResults() {\n  const queryParams = useRecoilValue_TRANSITION_SUPPORT_UNSTABLE(queryParamsAtom);\n  const results = useRecoilValue_TRANSITION_SUPPORT_UNSTABLE(myQuerySelector(queryParams));\n  return results;\n}\n\nfunction MyApp() {\n  const [queryParams, setQueryParams] = useRecoilState_TRANSITION_SUPPORT_UNSTABLE(queryParamsAtom);\n  const [inTransition, startTransition] = useTransition();\n  return (\n    &lt;div&gt;\n      {inTransition ? &lt;div&gt;[Loading new results...]&lt;/div&gt; : &#x27;&#x27;}\n      Results: &lt;React.Suspense&gt;&lt;QueryResults /&gt;&lt;/React.Suspense&gt;\n      &lt;button\n        onClick={() =&gt; {\n          startTransition(() =&gt; {\n            setQueryParams(...new params...);\n          });\n        }\n      &gt;\n        Start New Query\n      &lt;/button&gt;\n    &lt;/div&gt;\n  );\n}\n</code></pre><h2>New Features</h2><ul><li>Recoil Callbacks<ul><li><a href=\"/docs/api-reference/core/useRecoilCallback\"><code>useRecoilCallback()</code></a> can now also refresh selector caches, similar to <a href=\"/docs/api-reference/core/useRecoilRefresher\"><code>useRecoilRefresher_UNSTABLE()</code></a>. (<a href=\"https://github.com/facebookexperimental/Recoil/pull/1413\">#1413</a>)</li><li>Callbacks from selectors using <a href=\"/docs/api-reference/core/selector#returning-objects-with-callbacks\"><code>getCallback()</code></a> can now mutate, refresh, and transact state in addition to reading it, similar to <a href=\"/docs/api-reference/core/useRecoilCallback\"><code>useRecoilCallback()</code></a>. (<a href=\"https://github.com/facebookexperimental/Recoil/pull/1498\">#1498</a>)</li></ul></li><li>Store IDs - A <code>StoreID</code> can now be obtained using <a href=\"/docs/api-reference/core/useRecoilStoreID\"><code>useRecoilStoreID()</code></a> (<a href=\"https://github.com/facebookexperimental/Recoil/pull/1417\">#1417</a>) or the <code>storeID</code> parameter in <a href=\"/docs/guides/atom-effects\">atom effects</a>  (<a href=\"https://github.com/facebookexperimental/Recoil/pull/1414\">#1414</a>).</li><li><a href=\"/docs/api-reference/core/Loadable#examples\"><code>RecoilLoadable.of()</code></a> and <a href=\"/docs/api-reference/core/Loadable#examples\"><code>RecoilLoadable.all()</code></a> factories now accept either literal values, async Promises, or Loadables.  This is comparable to <code>Promise.resolve()</code> and <code>Promise.all()</code>  (<a href=\"https://github.com/facebookexperimental/Recoil/pull/1455\">#1455</a>, <a href=\"https://github.com/facebookexperimental/Recoil/pull/1442\">#1442</a>).</li><li>Add <code>.isRetained()</code> method for Snapshots and check if snapshot is already released when using <code>.retain()</code> in development (<a href=\"https://github.com/facebookexperimental/Recoil/pull/1546\">#1546</a>)</li></ul><h2>Breaking Changes</h2><ul><li>Atom Effects<ul><li>Rename option from <code>effects_UNSTABLE</code> to just <code>effects</code>, as the interface is mostly stabilizing. (<a href=\"https://github.com/facebookexperimental/Recoil/pull/1520\">#1520</a>)</li><li><a href=\"/docs/guides/atom-effects\">Atom effect</a> initializations takes precedence over <code>&lt;RecoilRoot initializeState={...}&gt;</code>. (<a href=\"https://github.com/facebookexperimental/Recoil/pull/1509\">#1509</a>)</li></ul></li><li><code>useGetRecoilValueInfo_UNSTABLE()</code> and <code>Snapshot#getInfo_UNSTABLE()</code> always report the node <code>type</code>. (<a href=\"https://github.com/facebookexperimental/Recoil/pull/1547\">#1547</a>)</li><li>The <a href=\"/blog/2021/05/14/0.3.0-released#breaking-change-preparing-for-memory-management\">0.3</a> release introduced the need to retain Snapshots for later use, but it was mostly a warning.  Now it is necessary to retain a Snapshot for asynchronous selectors to resolve.  See the documentation <a href=\"/docs/api-reference/core/Snapshot#asynchronous-use-of-snapshots\">here</a> and <a href=\"/docs/guides/testing#testing-async-selectors\">here</a>.  Future releases will further enforce this as garbage collection is released.</li></ul><h2>Other Fixes and Optimizations</h2><ul><li>Reduce overhead of snapshot cloning<ul><li>Only clone the current snapshot for callbacks if the callback actually uses it. (<a href=\"https://github.com/facebookexperimental/Recoil/pull/1501\">#1501</a>)</li><li>Cache the cloned snapshots from callbacks unless there was a state change. (<a href=\"https://github.com/facebookexperimental/Recoil/pull/1533\">#1533</a>)</li></ul></li><li>Fix transitive selector refresh for some cases (<a href=\"https://github.com/facebookexperimental/Recoil/pull/1409\">#1409</a>)</li><li>Fix some corner cases with async selectors and multiple stores (<a href=\"https://github.com/facebookexperimental/Recoil/pull/1568\">#1568</a>)</li><li>Atom effects<ul><li>Run atom effects when atoms are initialized from a <code>set()</code> during a transaction from <a href=\"/docs/api-reference/core/useRecoilTransaction\"><code>useRecoilTransaction_UNSTABLE()</code></a> (<a href=\"https://github.com/facebookexperimental/Recoil/pull/1466\">#1466</a>, <a href=\"https://github.com/facebookexperimental/Recoil/pull/1569\">#1569</a>)</li><li>Atom effects are cleaned up when initialized by a Snapshot which is released. (<a href=\"https://github.com/facebookexperimental/Recoil/pull/1511\">#1511</a>, <a href=\"https://github.com/facebookexperimental/Recoil/pull/1532\">#1532</a>)</li><li>Unsubscribe <code>onSet()</code> handlers in atom effects when atoms are cleaned up. (<a href=\"https://github.com/facebookexperimental/Recoil/pull/1509\">#1509</a>)</li><li>Call <code>onSet()</code> when atoms are initialized with <code>&lt;RecoilRoot initializeState={...} &gt;</code> (<a href=\"https://github.com/facebookexperimental/Recoil/pull/1519\">#1519</a>, <a href=\"https://github.com/facebookexperimental/Recoil/pull/1511\">#1511</a>)</li></ul></li><li>Avoid extra re-renders in some cases when a component uses a different atom/selector. (<a href=\"https://github.com/facebookexperimental/Recoil/pull/825\">#825</a>)</li><li><code>&lt;RecoilRoot&gt;</code> will only call <code>initializeState()</code> once during the initial render. (<a href=\"https://github.com/facebookexperimental/Recoil/pull/1372\">#1372</a>)</li><li>Lazily compute and memoize the results of lazy properties, such as from <code>useGetRecoilValueInfo()</code> or <code>Snapshot#getInfo_UNSTABLE()</code>. (<a href=\"https://github.com/facebookexperimental/Recoil/pull/1548\">#1548</a>, <a href=\"https://github.com/facebookexperimental/Recoil/pull/1549\">#1549</a>)</li></ul>",
            "url": "https://recoiljs.org/blog/2022/01/28/0.6.0-release",
            "title": "Recoil 0.6",
            "summary": "Recoil 0.6 introduces improved support for React 18, including concurrent rendering and transitions, along with new APIs, fixes, and optimizations.",
            "date_modified": "2022-01-28T00:00:00.000Z"
        },
        {
            "id": "/2021/11/03/0.5.0-release",
            "content_html": "<p>Welcome to Recoil 0.5 with a few new APIs and improvements.</p><h2>Hook for refreshing selectors</h2><p>The <a href=\"/docs/api-reference/core/useRecoilRefresher\"><code>useRecoilRefresher_UNSTABLE()</code></a> hook has been added for refreshing selectors that execute data queries.  This is useful if you just want to refresh for newer data or retry due to an error.  (<a href=\"https://github.com/facebookexperimental/Recoil/pull/972\">#972</a>, <a href=\"https://github.com/facebookexperimental/Recoil/pull/1294\">#1294</a>, <a href=\"https://github.com/facebookexperimental/Recoil/pull/1302\">#1302</a>)</p><h2>Atom effect improvements</h2><ul><li>Add <code>isReset</code> parameter to <code>onSet()</code> callback to know if the atom was reset.  (<a href=\"https://github.com/facebookexperimental/Recoil/pull/1358\">#1358</a>, <a href=\"https://github.com/facebookexperimental/Recoil/pull/1345\">#1345</a>)</li><li>Add <code>getLoadable()</code>, <code>getPromise()</code>, and <code>getInfo_UNSTABLE()</code> for reading other atoms.  (<a href=\"https://github.com/facebookexperimental/Recoil/pull/1205\">#1205</a>, <a href=\"https://github.com/facebookexperimental/Recoil/pull/1210\">#1210</a>)</li></ul><h2>Loadable factories</h2><p>The <a href=\"/docs/api-reference/core/Loadable#creating-loadables\"><code>RecoilLoadable</code></a> interface is now available for making your own <code>Loadable</code> objects.  (<a href=\"https://github.com/facebookexperimental/Recoil/pull/1263\">#1263</a>, <a href=\"https://github.com/facebookexperimental/Recoil/pull/1264\">#1264</a>, <a href=\"https://github.com/facebookexperimental/Recoil/pull/1312\">#1312</a>)</p><h2>Other fixes and improvements</h2><ul><li>Allow class instances in family parameters for Flow (<a href=\"https://github.com/facebookexperimental/Recoil/pull/1215\">#1215</a>)</li><li><code>Loadable</code> improvements:<ul><li>Ability to map Loadables with other Loadables. (<a href=\"https://github.com/facebookexperimental/Recoil/pull/1180\">#1180</a>)</li><li>Re-implement Loadable as classes. (<a href=\"https://github.com/facebookexperimental/Recoil/pull/1315\">#1315</a>)</li></ul></li><li>Fix user-thrown promises in selectors for some cases.</li><li>Improved dev-mode checks:<ul><li>Atoms freeze default, initialized, and async values.  Selectors should not freeze upstream dependencies. (<a href=\"https://github.com/facebookexperimental/Recoil/pull/1261\">#1261</a>, <a href=\"https://github.com/facebookexperimental/Recoil/pull/1259\">#1259</a>)</li><li>Perform runtime check that required options are provided when creating atoms and selectors. (<a href=\"https://github.com/facebookexperimental/Recoil/pull/1324\">#1324</a>)</li></ul></li><li>Upgrade Prettier version (<a href=\"https://github.com/facebookexperimental/Recoil/pull/1366\">#1366</a>)</li></ul><p><em>Also lots of restructuring in preparation for the upcoming <code>recoil-sync</code> library release...</em></p>",
            "url": "https://recoiljs.org/blog/2021/11/03/0.5.0-release",
            "title": "Recoil 0.5",
            "summary": "Welcome to Recoil 0.5 with a few new APIs and improvements.",
            "date_modified": "2021-11-03T00:00:00.000Z"
        },
        {
            "id": "/2021/08/26/0.4.1-release",
            "content_html": "<p>Recoil 0.4.1 has been released with some performance optimizations and fixes focused on optimizing when React will re-render components based on Recoil state changes.</p><ul><li>Components using selectors will no longer re-render if the selector evaluates to an equivalent value, based on reference equality.</li><li>Components previously rendered twice on initial render when not using React&#x27;s Concurrent Mode.</li><li>When selectors have async dependencies that resolve, some environments of React that previously caused unnecessary re-renders no longer will.</li><li>Components did not always re-render properly when selectors changed async dependencies based on other dependencies.</li></ul>",
            "url": "https://recoiljs.org/blog/2021/08/26/0.4.1-release",
            "title": "Recoil 0.4.1",
            "summary": "Recoil 0.4.1 has been released with some performance optimizations and fixes focused on optimizing when React will re-render components based on Recoil state changes.",
            "date_modified": "2021-08-26T00:00:00.000Z"
        },
        {
            "id": "/2021/07/30/0.4.0-release",
            "content_html": "<p>We are pleased to announce the release of Recoil 0.4 with configurable selector caches, improved API for transactions with multiple atoms, and other optimizations and fixes.</p><h2>Configurable selector caches</h2><p>The new <a href=\"/docs/api-reference/core/selector#cache-policy-configuration\"><code>cachePolicy_UNSTABLE</code></a> property in <a href=\"/docs/api-reference/core/selector\">selectors</a> and <a href=\"/docs/api-reference/utils/selectorFamily\">selector families</a> allows you to configure the caching behavior of a selector&#x27;s internal cache.  This property can be useful for reducing memory in applications that have a large number of selectors or selectors that have a large number of changing dependencies.</p><p>Below is an example of how you might use this new property:</p><pre><code class=\"language-jsx\">const clockState = selector({\n  key: &#x27;clockState&#x27;,\n  get: ({get}) =&gt; {\n    const hour = get(hourState);\n    const minute = get(minuteState);\n    const second = get(secondState); // will re-run every second\n\n    return `${hour}:${minute}:${second}`;\n  },\n  cachePolicy_UNSTABLE: {\n    // Only store the most recent set of dependencies and their values\n    eviction: &#x27;most-recent&#x27;,\n  },\n});\n</code></pre><p>In the example above, <code>clockState</code> recalculates every second, adding a new set of dependency values to the internal cache, which may lead to a memory issue over time as the internal cache grows indefinitely. Using the <code>most-recent</code> eviction policy, the internal selector cache will only retain the most recent set of dependencies and their values, along with the actual selector value based on those dependencies, thus solving the memory issue.</p><p>Current eviction options are:</p><ul><li><code>lru</code> - evicts the least-recently-used value from the cache when the size exceeds <code>maxSize</code>.</li><li><code>most-recent</code> - retains only the most recent value.</li><li><code>keep-all</code> (default) - keeps all entries in the cache and does not evict.</li></ul><blockquote><p><strong><em>NOTE:</em></strong> <em>The default eviction policy (currently <code>keep-all</code>) may change in the future.</em></p></blockquote><h2>Transactions with multiple atoms</h2><p>Introducing an improved API for updating multiple atoms together as a single transaction.  The new <a href=\"/docs/api-reference/core/useRecoilTransaction\"><code>useRecoilTransaction_UNSTABLE()</code></a> hook is easier, more efficient, and safer than before.  This new hook should eventually replace most uses of <a href=\"/docs/api-reference/core/useRecoilCallback\"><code>useRecoilCallback()</code></a>, however this release is only an initial implementation with <a href=\"/docs/api-reference/core/useRecoilTransaction#current-limitations-and-future-vision\">certain limitations</a> that will be addressed in future releases.</p><h3>Example</h3><p>Suppose we have two atoms, <code>positionState</code> and <code>headingState</code>, and we&#x27;d like to update them together as part of a single action, where the new value of <code>positionState</code> is a function of <em>both</em> the current value of <code>positionState</code> and <code>headingState</code>.  You can accomplish this with a transaction, which must be a pure function without side-effects:</p><pre><code class=\"language-jsx\">const goForward = useRecoilTransaction_UNSTABLE(({get, set}) =&gt; (distance) =&gt; {\n  const heading = get(headingState);\n  const position = get(positionState);\n  set(positionAtom, {\n    x: position.x + cos(heading) * distance,\n    y: position.y + sin(heading) * distance,\n  });\n});\n</code></pre><p>Then you can execute the transaction by just calling <code>goForward(distance)</code> in an event handler.  This will update state based on the <em>current</em> values, not the state when the components rendered.  You can also read the values of previous writes during a transaction.  Because no other updates will be committed while the updater is executing, you will see a consistent store of state.</p><p>the previous approach using <a href=\"/docs/api-reference/core/useRecoilCallback\"><code>useRecoilCallback()</code></a> might have looked like the following:</p><pre><code class=\"language-jsx\">const goForward = useRecoilCallback(({snapshot, gotoSnapshot}) =&gt; (distance) =&gt; {\n  const mutatedSnapshot = snapshot.map(({get, set}) =&gt; {\n    const heading = get(headingState);\n    const position = get(positionState);\n    set(positionState, {\n      x: position.x + cos(heading) * distance,\n      y: position.y + sin(heading) * distance,\n    });\n  });\n  gotoSnapshot(mutatedSnapshot);\n});\n</code></pre><p>This has the following drawbacks:</p><ul><li>There is performance overhead for managing the full generality of snapshots.</li><li>There is more opportunity for bugs:  The snapshot might be retained and used in the future.  Since a snapshot contains the complete set of Recoil state, not just a changeset, that could accidentally rewind changes that occurred between creating and committing the snapshot.</li></ul><h3>Reducer Example</h3><p>You can also use this hook to create a reducer pattern of executing actions over multiple atoms:</p><pre><code class=\"language-jsx\">const reducer = useRecoilTransaction_UNSTABLE(({get, set}) =&gt; action =&gt; {\n  switch(action.type) {\n    case &#x27;goForward&#x27;:\n      const heading = get(headingState);\n      set(positionState, position =&gt; {\n        x: position.x + cos(heading) * action.distance,\n        y: position.y + sin(heading) * action.distance,\n      });\n      break;\n\n    case &#x27;turn&#x27;:\n      set(headingState, action.heading);\n      break;\n  }\n});\n</code></pre><h2>Fixes and Optimizations</h2><ul><li>Fix TypeScript typing for <code>selectorFamily()</code>, <code>getCallback()</code>, <code>useGetRecoilValueInfo()</code>, and <code>Snapshot#getNodes()</code> (<a href=\"https://github.com/facebookexperimental/Recoil/pull/1060\">#1060</a>, <a href=\"https://github.com/facebookexperimental/Recoil/pull/1116\">#1116</a>, <a href=\"https://github.com/facebookexperimental/Recoil/pull/1123\">#1123</a>)</li><li>Allow mutable values in selectors (enabled via the <code>dangerouslyAllowMutability</code> selector option) to be used with <code>waitFor*()</code> helpers such as <a href=\"/docs/api-reference/utils/waitForAll\"><code>waitForAll()</code></a> (<a href=\"https://github.com/facebookexperimental/Recoil/pull/1074\">#1074</a>, <a href=\"https://github.com/facebookexperimental/Recoil/pull/1096\">#1096</a>)</li><li><a href=\"/docs/guides/atom-effects\">Atom Effects</a> fixes:<ul><li>Fix <code>onSet()</code> handler to get the proper new value when an atom is reset or has an async default Promise that resolves (<a href=\"https://github.com/facebookexperimental/Recoil/pull/1059\">#1059</a>, <a href=\"https://github.com/facebookexperimental/Recoil/pull/1050\">#1050</a>, <a href=\"https://github.com/facebookexperimental/Recoil/pull/738\">#738</a>) (This is a slightly breaking change because the actual new value will be provided to the handler instead of a <code>DefaultValue</code> placeholder)</li><li>Fix support for multiple Atom Effects cleanup handlers (<a href=\"https://github.com/facebookexperimental/Recoil/pull/1125\">#1125</a>)</li><li>Fix selector subscriptions when atoms with effects are initialized via a <code>Snapshot</code> (<a href=\"https://github.com/facebookexperimental/Recoil/pull/1135\">#1135</a>, <a href=\"https://github.com/facebookexperimental/Recoil/pull/1107\">#1107</a>)</li></ul></li><li>Optimization for async selectors when dependencies resolve to cached values (<a href=\"https://github.com/facebookexperimental/Recoil/pull/1037\">#1037</a>)</li><li>Remove unnecessary warning message (<a href=\"https://github.com/facebookexperimental/Recoil/pull/1034\">#1034</a>, <a href=\"https://github.com/facebookexperimental/Recoil/pull/1062\">#1062</a>)</li></ul>",
            "url": "https://recoiljs.org/blog/2021/07/30/0.4.0-release",
            "title": "Recoil 0.4",
            "summary": "We are pleased to announce the release of Recoil 0.4 with configurable selector caches, improved API for transactions with multiple atoms, and other optimizations and fixes.",
            "date_modified": "2021-07-30T00:00:00.000Z"
        },
        {
            "id": "/2021/05/14/0.3.0-released",
            "content_html": "<p>We are pleased to announce the release of Recoil 0.3 with more flexible RecoilRoot nesting, callback generation, preparation for memory management, optimizations, and bug fixes.</p><h2>New Features</h2><ul><li>You can now create a RecoilRoot that falls through to the surrounding root if one exists. This lets you create re-usable components that use Recoil, yet can be used within or without the context of a larger Recoil app. (<a href=\"https://github.com/facebookexperimental/Recoil/pull/973\">#973</a>)</li><li>You can now return Recoil callbacks from selectors. (<a href=\"https://github.com/facebookexperimental/Recoil/pull/989\">#989</a>)</li></ul><h2>Breaking Change: Preparing for Memory Management</h2><p>The next release of Recoil will have a breaking API change. Today&#x27;s release issues a console warning in development builds if you have any code that will need to be updated. Most apps will not need any code changes.</p><p>When we ship memory management, Snapshots (such as the one you get as an argument to <code>useRecoilCallback()</code>) will only be valid for the tick in which they are created. If you want to keep a Snapshot around for longer, you need to manually retain and then release it:</p><pre><code class=\"language-js\">const release = snapshot.retain();\ntry {\n  await someAsyncWork(snapshot);\n} finally {\n  release();\n}\n</code></pre><p>In 0.3.0, if you use a Snapshot that hasn&#x27;t been retained, you will get a console warning in development. There is no change in behavior in production. In the next release, it will throw an exception, in both development and production.</p><p>Retaining Snapshots should be avoided whenever possible, because it will prevent reclaiming of memory for all atoms for as long as that Snapshot is retained. Instead, pull out just the values you need before going to async.</p><h2>Bug Fixes, Performance, and Other Improvements</h2><ul><li>Reduced overhead when using <code>atomFamily</code>. One app with thousands of atoms saw 200MB less memory usage.</li><li>Fix a bug where errors throws from async selectors were not caught by React error boundaries. (<a href=\"https://github.com/facebookexperimental/Recoil/pull/998\">#998</a>, <a href=\"https://github.com/facebookexperimental/Recoil/pull/1017\">#1017</a>)</li><li>Experimental Atom Effects <code>onSet()</code> is no longer called when triggered from <code>setSelf()</code> initializing with a Promise or from the same <code>onSet()</code> handler.  (<a href=\"https://github.com/facebookexperimental/Recoil/pull/974\">#974</a>, <a href=\"https://github.com/facebookexperimental/Recoil/pull/979\">#979</a>, <a href=\"https://github.com/facebookexperimental/Recoil/pull/953\">#953</a>, <a href=\"https://github.com/facebookexperimental/Recoil/pull/986\">#986</a>)</li><li>Improved support for Safari. (<a href=\"https://github.com/facebookexperimental/Recoil/pull/967\">#967</a>, <a href=\"https://github.com/facebookexperimental/Recoil/pull/609\">#609</a>)</li><li>Values stored in selectors are now frozen in dev mode. (<a href=\"https://github.com/facebookexperimental/Recoil/pull/911\">#911</a>)</li><li>Improved TypeScript support for <code>Loadable</code>s.</li></ul>",
            "url": "https://recoiljs.org/blog/2021/05/14/0.3.0-released",
            "title": "Recoil 0.3",
            "summary": "We are pleased to announce the release of Recoil 0.3 with more flexible RecoilRoot nesting, callback generation, preparation for memory management, optimizations, and bug fixes.",
            "date_modified": "2021-05-14T00:00:00.000Z"
        },
        {
            "id": "/2021/03/22/0.2.0-released",
            "content_html": "<p>We are pleased to announce the release of Recoil 0.2.0. This release has a new, more reliable implementation of async selectors, greatly improved performance, and many bug fixes and improvements.</p><h2>Better Async Selectors</h2><p>We&#x27;ve reimplemented selectors to fix a number of corner cases that we didn&#x27;t handle before. For instance:</p><ul><li>Selectors can now add dependencies at any point in their async execution.</li><li>Selectors now start over if their dependencies change while they&#x27;re awaiting something.</li><li>Diamond dependency patterns now re-execute only the necessary selectors.</li></ul><p>These are just a few of the unit tests that pass only with the new implementation. You are now less likely to hit incorrect behavior when using async selectors in Recoil.</p><p>Many of the fixed bugs manifested as unnecessary execution of selectors. In one app that heavily uses async selectors, we observed an overall 15% decrease in the number of selector executions.</p><p>Christian Santos (<a href=\"https://github.com/csantos42\">@csantos42</a>) has been working on this with great diligence and we&#x27;re extremely happy to release it today.</p><h2>Scaling to Large Numbers of Atoms</h2><p>Recoil now uses <a href=\"https://en.wikipedia.org/wiki/Hash_array_mapped_trie\">special data structures</a> to maintain efficiency with large numbers of atoms. It is now hundreds of times faster when using 10,000 atoms.</p><h2>Logo</h2><p>Recoil now has a logo. Thanks to Gray Pegg (<a href=\"https://github.com/graypegg\">@graypegg</a>) for designing it and for sprucing up our website!</p><h2>Other Improvements</h2><ul><li>Error handling with <code>waitForAny()</code> has changed: It now lets you access the individual <code>Loadable</code>s corresponding to its arguments, even if one of them is in an error state. This makes it more consistent with <code>waitForNone()</code>.</li><li>Added a <code>waitForAllSettled()</code> helper analogous to <code>Promise.allSettled</code>.</li><li>Friendlier error message for misuse of <code>useRecoilCallback()</code>. (<a href=\"https://github.com/facebookexperimental/Recoil/pull/870\">#870</a>)</li><li>Friendlier error message if you try to use an async function as a selector setter, which is not supported. (<a href=\"https://github.com/facebookexperimental/Recoil/pull/777\">#777</a>)</li><li>Improved React Native support. (<a href=\"https://github.com/facebookexperimental/Recoil/pull/748\">#748</a>, <a href=\"https://github.com/facebookexperimental/Recoil/pull/702\">#702</a>)</li><li>Added a <code>useGetRecoilValueInfo_UNSTABLE()</code> hook for use by dev tools. (<a href=\"https://github.com/facebookexperimental/Recoil/pull/713\">#713</a>, <a href=\"https://github.com/facebookexperimental/Recoil/pull/714\">#714</a>)</li></ul><h2>Bug Fixes</h2><ul><li>Selectors now treat any non-<code>Promise</code> that is thrown as an error, rather than only instances of <code>Error</code>.</li><li><code>&lt;RecoilRoot&gt;</code> could sometimes have its state updated after being unmounted. (<a href=\"https://github.com/facebookexperimental/Recoil/pull/917\">#917</a>)</li><li>The error message for a missing <code>&lt;RecoilRoot&gt;</code> wasn&#x27;t displayed on React experimental releases. (<a href=\"https://github.com/facebookexperimental/Recoil/pull/712\">#712</a>)</li><li>Errors are no longer frozen. (<a href=\"https://github.com/facebookexperimental/Recoil/pull/852\">#852</a>)</li><li>Atom effects could fail to initialize atoms in certain cases (<a href=\"https://github.com/facebookexperimental/Recoil/pull/775\">#775</a>).</li><li>Async selectors would fail with multiple React roots.</li><li>IE 11 compatibility (<a href=\"https://github.com/facebookexperimental/Recoil/pull/894\">#894</a> and more)</li></ul><h2>Breaking Changes</h2><p>As mentioned above, the behavior of <code>waitForAny()</code> has changed. If you rely on the behavior that <code>waitForAny()</code> resulted in an error state if any of its arguments is in an error state, your code will break. Now it returns individual <code>Loadable</code>s for each argument, just as with the non-error state, and you can check for an error in each argument.</p><p>If you throw something that is not a <code>Promise</code> and not an <code>Error</code> from within a selector, it will now put the selector into an error state instead of treating the thrown object as a value.</p><h2>Future Work</h2><p>We are very close to releasing Memory Management, which will allow Recoil to automatically delete atoms and selectors that are no longer being used, configurable on a per-atom basis. This will also include configurable LRU caching for selectors.\nThese new features are in use internally at Facebook, but require a slight breaking change to the API. So our next release will start warning in cases where your code will break. The required changes are not difficult, and should be rare: Out of thousands of modules that import Recoil, we found less than half a dozen that required changes.</p>",
            "url": "https://recoiljs.org/blog/2021/03/22/0.2.0-released",
            "title": "Recoil 0.2",
            "summary": "We are pleased to announce the release of Recoil 0.2.0. This release has a new, more reliable implementation of async selectors, greatly improved performance, and many bug fixes and improvements.",
            "date_modified": "2021-03-22T00:00:00.000Z"
        },
        {
            "id": "/2020/10/30/0.1.1-released",
            "content_html": "<p>Welcome to Recoil version 0.1.1!  This release has performance improvements and introduces several <em>experimental</em> features such as support for React Native, working with Snapshots outside of React, and atom effects for managing side-effects of atoms such as logging, synchronization with external stores, persistence, etc.</p><p>Also, <a href=\"/docs/introduction/installation#nightly-builds\">nightly builds</a> are now available via the <code>nightly</code> branch.</p><h2>Performance</h2><p>Several changes to improve Recoil&#x27;s performance:</p><ul><li>Updates performed during <code>useRecoilCallback()</code> are now batched, which avoids copying data structures or performing updates for intermediate states.  This allowed setting 5,000 atoms in a loop to go from 10s -&gt; 25ms with some of our stress tests. (<a href=\"https://github.com/davidmccabe\">@davidmccabe</a>)</li><li>Recoil also now avoids looking up selector values in cache if the selector&#x27;s dependencies have not changed.  This improved some applications with complex data-flow graphs by 30-40x. (<a href=\"https://github.com/davidmccabe\">@davidmccabe</a>)</li></ul><h2>React Native (<em>Experimental</em>)</h2><p>Recoil should now work with the React Native environment.  However, similar to server side rendering, it is not officially supported. (<a href=\"https://github.com/facebookexperimental/Recoil/pull/114\">#114</a> - <a href=\"https://github.com/jacques-blom\">@jacques-blom</a>, <a href=\"https://github.com/mondaychen\">@mondaychen</a>)</p><h2>Atom Effects (<em>Experimental</em>)</h2><p><a href=\"/docs/guides/atom-effects\">Effects for atoms</a> simplifies managing side-effect policies for atoms on a per-atom basis as part of the <code>atom()</code> or <code>atomFamily()</code> definition.  Effects can be used for interesting applications such as <a href=\"/docs/guides/atom-effects#logging-example\">logging</a> and state synchronization or persistence with external storage such as <a href=\"/docs/guides/atom-effects#state-synchronization-example\">remote databases</a>, <a href=\"/docs/guides/atom-effects#local-storage-persistence\">local storage</a>, browser URL history, etc.  For example, you could use an atom as a local copy of some user state and provide an effect to subscribe to changes on a server to update the local copy and for local changes to write-through and update the server. (<a href=\"https://github.com/facebookexperimental/Recoil/pull/680\">#680</a>, <a href=\"https://github.com/facebookexperimental/Recoil/pull/380\">#380</a>, <a href=\"https://github.com/facebookexperimental/Recoil/pull/381\">#381</a>, <a href=\"https://github.com/facebookexperimental/Recoil/pull/384\">#384</a>, <a href=\"https://github.com/facebookexperimental/Recoil/pull/385\">#385</a>, <a href=\"https://github.com/facebookexperimental/Recoil/pull/448\">#448</a>, <a href=\"https://github.com/facebookexperimental/Recoil/pull/449\">#449</a>, <a href=\"https://github.com/facebookexperimental/Recoil/pull/412\">#412</a>, <a href=\"https://github.com/facebookexperimental/Recoil/pull/591\">#591</a>, <a href=\"https://github.com/facebookexperimental/Recoil/pull/634\">#634</a>, <a href=\"https://github.com/facebookexperimental/Recoil/pull/682\">#682</a> <!-- -->—<!-- --> <a href=\"https://github.com/drarmstr\">@drarmstr</a>, <a href=\"https://github.com/csantos4242\">@csantos4242</a>)</p><h2>Snapshots for Testing (<em>Experimental</em>)</h2><p>Snapshots can now be <a href=\"/docs/api-reference/core/Snapshot#building-a-snapshot\">constructed outside of a React context</a>.  This can be useful for <a href=\"/docs/guides/testing\">testing</a> or evaluating selectors outside of a React context. (<a href=\"https://github.com/facebookexperimental/Recoil/pull/649\">#649</a> <!-- -->—<!-- --> <a href=\"https://github.com/drarmstr\">@drarmstr</a>, <a href=\"https://github.com/habond\">@habond</a>)</p><h2>Bug Fixes</h2><ul><li>This update has various bug fixes for testing and infrastructure. (<a href=\"https://github.com/facebookexperimental/Recoil/pull/555\">#555</a>, <a href=\"https://github.com/facebookexperimental/Recoil/pull/587\">#587</a>, <a href=\"https://github.com/facebookexperimental/Recoil/pull/588\">#588</a>, <a href=\"https://github.com/facebookexperimental/Recoil/pull/590\">#590</a>, <a href=\"https://github.com/facebookexperimental/Recoil/pull/635\">#635</a>, <a href=\"https://github.com/facebookexperimental/Recoil/pull/631\">#631</a>, <a href=\"https://github.com/facebookexperimental/Recoil/pull/683\">#683</a>, <a href=\"https://github.com/facebookexperimental/Recoil/pull/684\">#684</a>, <a href=\"https://github.com/facebookexperimental/Recoil/pull/686\">#686</a> <!-- -->—<!-- --> <a href=\"https://github.com/aaronabramov\">@aaronabramov</a>, <a href=\"https://github.com/mondaychen\">@mondaychen</a>, <a href=\"https://github.com/drarmstr\">@drarmstr</a>, <a href=\"https://github.com/mallchel\">@mallchel</a>, <a href=\"https://github.com/davidmccabe\">@davidmccabe</a>, <a href=\"https://github.com/csantos4242\">@csantos4242</a>)</li><li>Do not freeze objects which should not be frozen. (<a href=\"https://github.com/facebookexperimental/Recoil/pull/597\">#597</a>, <a href=\"https://github.com/facebookexperimental/Recoil/pull/633\">#633</a>, <a href=\"https://github.com/facebookexperimental/Recoil/pull/672\">#672</a> <!-- -->—<!-- --> <a href=\"https://github.com/RinGoku\">@RinGoku</a>, <a href=\"https://github.com/a-sane\">@a-sane</a>)</li><li>TypeScript typing for <code>Snapshot</code>. (<a href=\"https://github.com/facebookexperimental/Recoil/pull/687\">#687</a> <!-- -->—<!-- --> <a href=\"https://github.com/kevinfrei\">@kevinfrei</a>, <a href=\"https://github.com/drarmstr\">@drarmstr</a>, <a href=\"https://github.com/habond\">@habond</a>)</li><li>Additional testing for <code>waitForAll()</code> concurrency. (<a href=\"https://github.com/facebookexperimental/Recoil/pull/681\">#681</a> <!-- -->—<!-- --> <a href=\"https://github.com/drarmstr\">@drarmstr</a>)</li></ul><h2>Future Work</h2><p>In a future release, Recoil will automatically free the memory used by atoms and selectors that are no longer used, and will perform better with larger numbers of atoms. (<a href=\"https://github.com/davidmccabe\">@davidmccabe</a>)</p><p>Releasing our prototype Chrome developer tools. (<a href=\"https://github.com/maxijb\">@maxijb</a>)</p><p>Libraries of effects for common state persistence, such as browser local storage or URL history. (<a href=\"https://github.com/bezi\">@bezi</a>)</p><p>Thanks for your continued interest in Recoil!</p>",
            "url": "https://recoiljs.org/blog/2020/10/30/0.1.1-released",
            "title": "Recoil 0.1.1",
            "summary": "Welcome to Recoil version 0.1.1!  This release has performance improvements and introduces several experimental features such as support for React Native, working with Snapshots outside of React, and atom effects for managing side-effects of atoms such as logging, synchronization with external stores, persistence, etc.",
            "date_modified": "2020-10-30T00:00:00.000Z"
        },
        {
            "id": "/2020/09/15/0.0.11-released",
            "url": "https://recoiljs.org/blog/2020/09/15/0.0.11-released",
            "title": "Recoil 0.0.11",
            "summary": "Today we are releasing Recoil 0.0.11. It contains bug fixes, new features, better performance, and experimental compatibility with Concurrent Mode. Thank you so much to everyone who contributed to this release!",
            "date_modified": "2020-09-15T00:00:00.000Z"
        },
        {
            "id": "/2020/06/18/0.0.10-released",
            "content_html": "<p>Recoil 0.0.9 and 0.0.10 is being released with some bug fixes, <a href=\"#typescript-support\">TypeScript support</a>, and a new API for <a href=\"#recoil-snapshots\">Recoil Snapshots</a> to observe, inspect, and manage global Recoil atom state.  Thanks again to everyone who helped make this possible and stay tuned for more exciting developments coming soon!</p><h2>Bug Fixes</h2><ul><li>Fixes for Server Side Rendering, though we do not officially support it yet. (#233, #220, #284) - Thanks @fyber-LJX, @Chrischuck, and @aulneau</li><li>Fix selectors recording dependency subscriptions in some cases (#296) - Thanks @drarmstr</li><li>Fix updaters in <code>useRecoilCallback()</code> getting current state (#260) - Thanks @drarmstr</li><li>Fix error messages when throwing certain errors in the open-source build. (#199) - Thanks @jonthomp</li><li>Reduce Flow errors for open-source builds (#308) - Thanks @Komalov</li></ul><h2>Improvements</h2><ul><li>Throw error with meaningful message if user doesn&#x27;t use an atom or selector with most Recoil hooks (#205) - Thanks @alexandrzavalii</li><li>Improve testing (#321, #318, #294, #262, #295) - Thanks @aaronabramov, @Komalov, @mondaychen, @drarmstr, and @tyler-mitchell</li><li>Improve open-source build (#249, #203, #33) - Thanks to @tony-go, @acutmore, and @jaredpalmer</li></ul><h2>TypeScript support</h2><p>TypeScript support is being rolled into the Recoil GitHub repository instead of <code>DefinitelyTyped</code> to help better keep it in sync with the API. (#292 &amp; #339) - Thanks @csantos42</p><h1>Recoil Snapshots</h1><p>#312, #311, #310, #309, #260, #259, #258, #257, #256 - Thanks @drarmstr and the rest of the team</p><p>We are introducing the concept of a <a href=\"/docs/api-reference/core/Snapshot\"><code>Snapshot</code></a> to Recoil.  A <code>Snapshot</code> is an immutable snapshot of the state of Recoil atoms.  This is intended to standardize the API for observing, inspecting, and managing global Recoil state and derived state.  It’s useful for dev tools, global state synchronization, history, and navigation.</p><h2>API</h2><h3>Reading Snapshots</h3><p>The <code>Snapshot</code> class exposes the following methods for getting the values of individual Recoil atoms and selectors:</p><pre><code class=\"language-jsx\">class Snapshot {\n  getLoadable: &lt;T&gt;(RecoilValue&lt;T&gt;) =&gt; Loadable&lt;T&gt;;\n  getPromise: &lt;T&gt;(RecoilValue&lt;T&gt;) =&gt; Promise&lt;T&gt;;\n  ...\n}\n</code></pre><p>Snapshots are read-only with respect to atom state.  They can be used to read atom state and evaluate selector derived state.  For asynchronous selectors, the <code>getPromise()</code> method can be used to wait for the evaluated value so you can see what the selector value would be based on the static atom state.</p><h3>Transforming Snapshots</h3><p>There are cases where you may wish to mutate a snapshot.  While snapshots are immutable, they have methods to map themselves with a set of transformations to a new immutable snapshot.  The map methods take a callback that is passed a <code>MutableSnapshot</code>, which is mutated throughout the callback and will ultimately become the new snapshot returned by the mapping operation.</p><pre><code class=\"language-jsx\">class Snapshot {\n  ...\n  map: (MutableSnapshot =&gt; void) =&gt; Snapshot;\n  asyncMap: (MutableSnapshot =&gt; Promise&lt;void&gt;) =&gt; Promise&lt;Snapshot&gt;;\n}\n\nclass MutableSnapshot {\n  set: &lt;T&gt;(RecoilState&lt;T&gt;, T | DefaultValue | (T =&gt; T | DefaultValue)) =&gt; void;\n  reset: &lt;T&gt;(RecoilState&lt;T&gt;) =&gt; void;\n}\n</code></pre><p>Notice that <code>set()</code> and <code>reset()</code> have the same signature as the callbacks provided to a writeable selector’s <code>set()</code> function.</p><p><strong>Example</strong></p><pre><code class=\"language-jsx\">  const newSnapshot = snapshot.map(({set}) =&gt; set(myAtom, 42));\n</code></pre><h2>Hooks</h2><p>Recoil has the following hooks for working with snapshots:</p><ul><li><a href=\"/docs/api-reference/core/useRecoilSnapshot\"><strong><code>useRecoilSnapshot()</code></strong></a> - Synchronous access to snapshot</li><li><a href=\"/docs/api-reference/core/useRecoilCallback\"><strong><code>useRecoilCallback()</code></strong></a> - Asynchronous access to snapshot</li><li><a href=\"/docs/api-reference/core/useRecoilTransactionObserver\"><strong><code>useRecoilTransactionObserver()</code></strong></a> - Subscribe to snapshots of all state updates</li><li><a href=\"/docs/api-reference/core/useGotoRecoilSnapshot\"><strong><code>useGotoRecoilSnapshot()</code></strong></a> - Update current state to match snapshot</li></ul><h3>useRecoilSnapshot()</h3><pre><code class=\"language-jsx\">function useRecoilSnapshot(): Snapshot\n</code></pre><p>You can use this hook to synchronously obtain a snapshot to the current state while rendering a component.  While conceptually simple, this hook will subscribe any component that uses it to any Recoil state change so it always renders with a snapshot of the current state.  Therefore, be careful using this hook.  One example when you may want to use it is for supporting server-side rendering where you need to synchronously have the state with the first render.  In the future, we may provide the ability to debounce for performance.</p><p><strong>Example</strong></p><p>Define a <code>&lt;LinkToNewState&gt;</code> component that renders an <code>&lt;a&gt;</code> anchor with an <code>href</code> based on the current state with a mutation applied.  In this example <code>uriFromSnapshot()</code> is some user-defined function which encodes the current state in the URI which can be restored when loading the page.</p><pre><code class=\"language-jsx\">function LinkToNewState() {\n  const snapshot = useRecoilSnapshot();\n  const newSnapshot = snapshot.map(({set}) =&gt; set(myAtom, 42));\n  return &lt;a href={uriFromSnapshot(newSnapshot)}&gt;Click Me!&lt;/a&gt;;\n}\n</code></pre><p>This is a simplified example.  We have a helper like this for generating links in our browser history persistence library coming soon which is more extensible and optimized.  For example, it will hijack the click handler to update local state without needing to go through the browser history.</p><h3>useRecoilCallback()</h3><pre><code class=\"language-jsx\">type CallbackInterface = {\n  snapshot: Snapshot,\n  gotoSnapshot: Snapshot =&gt; void,\n  set: &lt;T&gt;(RecoilState&lt;T&gt;, (T =&gt; T) | T) =&gt; void,\n  reset: &lt;T&gt;(RecoilState&lt;T&gt;) =&gt; void,\n};\n\nfunction useRecoilCallback&lt;Args, Return&gt;(\n  callback: CallbackInterface =&gt; (...Args) =&gt; ReturnValue,\n  deps?: $ReadOnlyArray&lt;mixed&gt;,\n): (...Args) =&gt; ReturnValue\n</code></pre><p>The <code>useRecoilCallback()</code> hook is similar to the React <a href=\"https://reactjs.org/docs/hooks-reference.html#usecallback\"><code>useCallback()</code></a> hook for producing a callback function.  But, instead of just providing an input callback function you wrap it with a function providing a callback interface parameter that gives you access to a <code>Snapshot</code> and <code>set()</code>/<code>reset()</code> callbacks to update the current global state.  The provided <code>Snapshot</code> represents the state when the callback is called, not when the callback function was originally created.</p><p>NOTE: This is a slight breaking change in the API, but we are still on version <code>0.0.x</code> of Recoil and haven’t fully started semantic versioning yet.</p><p><code>useRecoilCallback()</code> also takes an optional <code>deps</code> array parameter for controlling memoization.  You can extend the <code>react-hooks/exhaustive-deps</code> lint rule for ensuring this is properly used.</p><p>Some motivations for using <code>useRecoilCallback()</code>:</p><ul><li><p>Asynchronously use Recoil state without subscribing a React component to re-render if the atom or selector is updated.</p></li><li><p>Deferring expensive lookups to an async action that you don&#x27;t want to do at render-time.</p></li><li><p>Performing side-effects where you would like to also read or write to Recoil state.</p></li><li><p>Dynamically updating an atom or selector where we may not know at render-time which atom or selector we will want to update, so we can&#x27;t use <a href=\"https://recoiljs.org/docs/api-reference/core/useSetRecoilState\"><code>useSetRecoilState()</code></a>.</p></li><li><p>Pre-fetching before rendering</p></li></ul><p><strong>Example</strong></p><p>Button component which will evaluate an expensive selector when clicked on.</p><pre><code class=\"language-jsx\">function ShowDetailsButton() {\n  const onClick = useRecoilCallback(({snapshot}) =&gt; async () =&gt; {\n    const data = await snapshot.getPromise(expensiveQuery);\n    showPopup(data);\n  });\n\n  return &lt;button onClick={onClick}&gt;Show Details&lt;/button&gt;;\n}\n</code></pre><h3>useRecoilTransactionObserver()</h3><pre><code class=\"language-jsx\">function useRecoilTransactionObserver_UNSTABLE(({\n  snapshot: Snapshot,\n  previousSnapshot: Snapshot,\n}) =&gt; void)\n</code></pre><p>This hook subscribes a callback to be executed every time there is a change to Recoil atom state.  Multiple updates may be batched together in a single transaction.  This hook is great for persisting state changes, dev tools, building history, &amp;c.  In the future, we may allow the ability to subscribe to specific conditions or provide debouncing for performance.</p><p><strong>Debug Observer Example</strong></p><pre><code class=\"language-jsx\">function DebugObserver() {\n  useRecoilTransactionObserver_UNSTABLE(({snapshot}) =&gt; {\n    window.myDebugState = {\n      a: snapshot.getLoadable(atomA).contents,\n      b: snapshot.getLoadable(atomB).contents,\n    };\n  });\n  return null;\n}\n</code></pre><h3>useGotoRecoilState()</h3><pre><code class=\"language-jsx\">function useGotoRecoilSnapshot(): Snapshot =&gt; void\n</code></pre><p>This hook returns a callback which takes a <code>Snapshot</code> as a parameter and will update the current <code>&lt;RecoilRoot&gt;</code> state to match this atom state.</p><p><strong>Time Travel Example</strong></p><p>Example list of history of state changes with the ability to go back and restore previous state.</p><pre><code class=\"language-jsx\">function TimeTravelObserver() {\n  const [snapshots, setSnapshots] = useState([]);\n\n  useRecoilTransactionObserver_UNSTABLE(({snapshot}) =&gt; {\n    setSnapshots([...snapshots, snapshot]);\n  });\n\n  const gotoSnapshot = useGotoRecoilSnapshot();\n\n  return (\n    &lt;ol&gt;\n      {snapshots.map((snapshot, i) =&gt; (\n        &lt;li key={i}&gt;\n          Snapshot {i}\n          &lt;button onClick={() =&gt; gotoSnapshot(snapshot)}&gt;\n            Restore\n          &lt;/button&gt;\n        &lt;/li&gt;\n      )}\n    &lt;/ol&gt;\n  );\n}\n</code></pre><h2>State Initialization</h2><p>The <code>&lt;RecoilRoot&gt;</code> component also has an <code>initializeState</code> prop which can be used to initialize the atom state.  This prop takes a function with a <code>MutableSnapshot</code> parameter that can be used to setup the initial atom state.  This can be helpful for loading persisted state when you know all atoms in advance.  It can be useful for server-side rendering where the state should be setup synchronously for the first render.</p><p><strong>Example</strong></p><pre><code class=\"language-jsx\">function MyApp() {\n  return (\n    &lt;RecoilRoot\n      initializeState={({set}) =&gt; {\n        for (const [atom, value] of atoms) {\n          set(atom, value);\n        }\n      }}\n    &gt;\n      &lt;AppContents /&gt;\n    &lt;/RecoilRoot&gt;\n  );\n}\n</code></pre><h2>What’s Next?</h2><p>Snapshots allow us to observe and synchronize the global state.  But, what if we want a more granular and composable system to work with individual atoms?  We’re working on the concept of <em>Atom Effects</em> for observing and dealing with side-effects at the atom level.  This will make it easier to persist state or bi-directionally sync with mutable storage.  Think of synchronizing state with the browser URI history, browser local storage, RESTful APIs, &amp;c.  Coming soon!</p><p>The <code>Snapshot</code> API introduced here allows us to inspect the current state for individual atoms and selectors.  We’ll be expanding the API to be able to inspect the set of available nodes and explore the data-flow graph structure.  This will be powerful for building dev tools.  Stay tuned!</p><p>And, of course, we still have exiciting support for React Concurrent Mode and improved speed, scalability, and memory management in the works.</p>",
            "url": "https://recoiljs.org/blog/2020/06/18/0.0.10-released",
            "title": "Recoil 0.0.10",
            "summary": "Recoil 0.0.9 and 0.0.10 is being released with some bug fixes, TypeScript support, and a new API for Recoil Snapshots to observe, inspect, and manage global Recoil atom state.  Thanks again to everyone who helped make this possible and stay tuned for more exciting developments coming soon!",
            "date_modified": "2020-06-18T00:00:00.000Z"
        },
        {
            "id": "/2020/05/30/0.0.8-released",
            "content_html": "<p>Today we are releasing Recoil 0.0.8. It contains bug fixes and new features. Thanks so much to everyone who contributed to this release! It&#x27;s been amazing to see so many people contribute.</p><h2>Bug Fixes</h2><ul><li>Fixed a bug where atoms that stored self-referential structures would cause an infinite loop. (@n3tr in #153)</li><li>Fixed bugs affecting Server-Side Rendering. (@sbaudray in #53)</li><li>Fixed build system and repository syncing problems. Many people contributed to this, especially @mondaychen and including\n@claudiopro, @dustinsoftware, @jacques-blom, @jaredpalmer, @kentcdodds, @leushkin, and @tony-go. It remains to get Jest and Flow to behave the same between internal and OSS.</li></ul><h2>Features</h2><h3>TypeScript support</h3><p>TypeScript definitions are now available via the <code>DefinitelyTyped</code> repository.</p><h3><code>atomFamily</code> and <code>selectorFamily</code></h3><p>These utilities help you create collections of related atoms or selectors, one for each value of some parameter. Instaed of manually creating a memoized function that returns an atom or selector, you can use <code>atomFamily</code> and <code>selectorFamily</code>. In the future, these utilities will also help with memory management.</p><p>The <code>atomFamily</code> function returns a function from some parameter to an atom, creating a new atom for each value of the parameter that is passed in. For example, suppose you wanted to store a set of coordinates <code>{x: number, y: number}</code> for every member of a collection identified by some <code>ID</code>. Then you could write:</p><pre><code class=\"language-jsx\">const coordinatesForID = atomFamily&lt;{x: number, y: number}, ID&gt;({\n    key: &#x27;coordinatesForID&#x27;,\n    default: {x: 0, y: 0},\n});\n</code></pre><p>and then access that state as follows:</p><pre><code class=\"language-jsx\">function MyComponent({id}) {\n    const [coordinates, setCoordinates] = useRecoilState(\n        coordinatesForID(id)\n    );\n    ...\n}\n</code></pre><p>Each <code>ID</code> passed to <code>coordinatesForID</code> will get its own independent atom containing the coordinates. Each of these atoms has its own subscriptions, so a component that uses the state for a single ID will only be subscribed to changes to that one ID.</p><p>Similarly, <code>selectorFamily</code> lets you create a different selector for each value of some parameter. For example, suppose you wanted to take each of those coordinates and rotate them by 180 degrees:</p><pre><code class=\"language-jsx\">const rotatedCoordinatesForID = selectorFamily&lt;{x: number, y: number}, ID&gt;({\n    key: &#x27;rotatedCoordinatesForID&#x27;,\n    get: id =&gt; ({get}) =&gt; {\n        const coordinates = get(coordinatesForID(id));\n        return {\n            x: -coordinates.x,\n            y: -coordinates.y,\n        };\n    }\n});\n</code></pre><p>Note that the <code>get</code> property of a selector family is a function that takes the parameter (in this case ID) and returns a function with a signature identical to the <code>get</code> property of a single selector. In general, this is how all of the options for atom families and selector families work.</p><h3>Concurrency helpers</h3><p>We&#x27;ve introduced selector families for controlling concurrency in async selectors:</p><ul><li><code>waitForAll</code>: requests all dependencies in parallel and waits for all of them to become available.</li><li><code>waitForAny</code>: requests all dependencies in parallel and waits for any one of them to become available.</li><li><code>waitForNone</code>: requests all dependencies in parallel but doesn&#x27;t wait for any of them.</li><li><code>noWait</code> requests a single dependency but doesn&#x27;t wait for it to become available.</li></ul><p>These can be used to retireve multiple dependencies in parallel and to write logic conditional on the status of an upstream dependency. For example, you can write a selector that conditionally provides a default value while an async process is in flight instead of propagating that loading state down to components.</p><h3><code>constSelector</code> and <code>errorSelector</code></h3><p>These selector families simply return a constant value or always throw a given error, respectively.</p><h3>readOnlySelector</h3><p>This simply wraps a read-write <code>RecoilState</code> in a read-only interface.</p><h2>What&#x27;s Next</h2><p>We&#x27;re working on improvements to the observation and persistence APIs, improved speed and memory management, and support for Concurrent Mode. Thanks so much for trying Recoil, we hope you&#x27;ll stick around and see what it becomes!</p>",
            "url": "https://recoiljs.org/blog/2020/05/30/0.0.8-released",
            "title": "Recoil 0.0.8",
            "summary": "Today we are releasing Recoil 0.0.8. It contains bug fixes and new features. Thanks so much to everyone who contributed to this release! It's been amazing to see so many people contribute.",
            "date_modified": "2020-05-30T00:00:00.000Z"
        }
    ]
}