CINXE.COM

<!doctype html> <html lang="zh-hans" dir="ltr"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width,initial-scale=1"> <meta name="generator" content="Docusaurus v2.0.0-beta.14"> <link rel="alternate" type="application/rss+xml" href="/zh-hans/blog/rss.xml" title="Recoil RSS Feed"> <link rel="alternate" type="application/atom+xml" href="/zh-hans/blog/atom.xml" title="Recoil Atom Feed"> <link rel="alternate" type="application/json" href="/zh-hans/blog/feed.json" title="Recoil JSON Feed"> <link rel="preconnect" href="https://www.google-analytics.com"> <script>window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)},ga.l=+new Date,ga("create","UA-44373548-46","auto"),ga("send","pageview")</script> <script async src="https://www.google-analytics.com/analytics.js"></script> <link rel="search" type="application/opensearchdescription+xml" title="Recoil" href="/zh-hans/opensearch.xml"><title data-react-helmet="true">Blog | Recoil</title><meta data-react-helmet="true" property="og:title" content="Blog | Recoil"><meta data-react-helmet="true" name="twitter:card" content="summary_large_image"><meta data-react-helmet="true" property="og:image" content="https://recoiljs.org/zh-hans/img/og-image.png"><meta data-react-helmet="true" name="twitter:image" content="https://recoiljs.org/zh-hans/img/og-image.png"><meta data-react-helmet="true" name="description" content="Blog"><meta data-react-helmet="true" property="og:description" content="Blog"><meta data-react-helmet="true" property="og:url" content="https://recoiljs.org/zh-hans/blog"><meta data-react-helmet="true" name="docsearch:language" content="zh-hans"><meta data-react-helmet="true" name="docsearch:docusaurus_tag" content="blog_posts_list"><link data-react-helmet="true" rel="icon" href="/zh-hans/img/favicon.png"><link data-react-helmet="true" rel="canonical" href="https://recoiljs.org/zh-hans/blog"><link data-react-helmet="true" rel="alternate" href="https://recoiljs.org/blog" hreflang="en"><link data-react-helmet="true" rel="alternate" href="https://recoiljs.org/fr/blog" hreflang="fr"><link data-react-helmet="true" rel="alternate" href="https://recoiljs.org/ko/blog" hreflang="ko"><link data-react-helmet="true" rel="alternate" href="https://recoiljs.org/zh-hans/blog" hreflang="zh-hans"><link data-react-helmet="true" rel="alternate" href="https://recoiljs.org/blog" hreflang="x-default"><link data-react-helmet="true" rel="preconnect" href="https://BH4D9OD16A-dsn.algolia.net" crossorigin="anonymous"><link rel="stylesheet" href="/zh-hans/assets/css/styles.d19c01d8.css"> <link rel="preload" href="/zh-hans/assets/js/runtime~main.8e652302.js" as="script"> <link rel="preload" href="/zh-hans/assets/js/main.f671ce00.js" as="script"> </head> <body> <script>!function(){function t(t){document.documentElement.setAttribute("data-theme",t)}var e=function(){var t=null;try{t=localStorage.getItem("theme")}catch(t){}return t}();t(null!==e?e:"light")}(),document.documentElement.setAttribute("data-announcement-bar-initially-dismissed",function(){try{return"true"===localStorage.getItem("docusaurus.announcement.dismiss")}catch(t){}return!1}())</script><div id="__docusaurus"> <div><a href="#" class="skipToContent_OuoZ">跳转到主要内容</a></div><div class="announcementBar_axC9" style="background-color:#20232a;color:#fff" role="banner"><div class="announcementBarContent_6uhP">Support Ukraine 🇺🇦 <a target="_blank" rel="noopener noreferrer" href="https://opensource.fb.com/support-ukraine">Help Provide Humanitarian Aid to Ukraine</a>.</div></div><nav class="navbar navbar--fixed-top"><div class="navbar__inner"><div class="navbar__items"><button aria-label="Navigation bar toggle" class="navbar__toggle clean-btn" type="button" tabindex="0"><svg width="30" height="30" viewBox="0 0 30 30" aria-hidden="true"><path stroke="currentColor" stroke-linecap="round" stroke-miterlimit="10" stroke-width="2" d="M4 7h22M4 15h22M4 23h22"></path></svg></button><a class="navbar__brand" target="_self" href="/zh-hans/"><div class="navbar__logo"><img src="/zh-hans/img/logo.svg" alt="Recoil" class="themedImage_TMUO themedImage--light_4Vu1"><img src="/zh-hans/img/logo--dark.svg" alt="Recoil" class="themedImage_TMUO themedImage--dark_uzRr"></div></a><a class="navbar__item navbar__link" href="/zh-hans/docs/introduction/installation">文档</a><a aria-current="page" class="navbar__item navbar__link navbar__link--active" href="/zh-hans/blog">Blog</a><a class="navbar__item navbar__link" href="/zh-hans/docs/recoil-sync/introduction">Recoil Sync</a><a class="navbar__item navbar__link" href="/zh-hans/docs/refine/Introduction">Refine</a><a class="navbar__item navbar__link" href="/zh-hans/docs/recoil-relay/introduction">GraphQL</a><a class="navbar__item navbar__link" href="/zh-hans/resources">Tutorials</a></div><div class="navbar__items navbar__items--right"><a href="https://github.com/facebookexperimental/Recoil" target="_blank" rel="noopener noreferrer" class="navbar__item navbar__link"><span>GitHub<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_wgqa"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"></path></svg></span></a><div class="navbar__item dropdown dropdown--hoverable dropdown--right"><a href="#" class="navbar__link"><span><svg viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" class="iconLanguage_EbrZ"><path fill="currentColor" d="M19.753 10.909c-.624-1.707-2.366-2.726-4.661-2.726-.09 0-.176.002-.262.006l-.016-2.063 3.525-.607c.115-.019.133-.119.109-.231-.023-.111-.167-.883-.188-.976-.027-.131-.102-.127-.207-.109-.104.018-3.25.461-3.25.461l-.013-2.078c-.001-.125-.069-.158-.194-.156l-1.025.016c-.105.002-.164.049-.162.148l.033 2.307s-3.061.527-3.144.543c-.084.014-.17.053-.151.143.019.09.19 1.094.208 1.172.018.08.072.129.188.107l2.924-.504.035 2.018c-1.077.281-1.801.824-2.256 1.303-.768.807-1.207 1.887-1.207 2.963 0 1.586.971 2.529 2.328 2.695 3.162.387 5.119-3.06 5.769-4.715 1.097 1.506.256 4.354-2.094 5.98-.043.029-.098.129-.033.207l.619.756c.08.096.206.059.256.023 2.51-1.73 3.661-4.515 2.869-6.683zm-7.386 3.188c-.966-.121-.944-.914-.944-1.453 0-.773.327-1.58.876-2.156a3.21 3.21 0 011.229-.799l.082 4.277a2.773 2.773 0 01-1.243.131zm2.427-.553l.046-4.109c.084-.004.166-.01.252-.01.773 0 1.494.145 1.885.361.391.217-1.023 2.713-2.183 3.758zm-8.95-7.668a.196.196 0 00-.196-.145h-1.95a.194.194 0 00-.194.144L.008 16.916c-.017.051-.011.076.062.076h1.733c.075 0 .099-.023.114-.072l1.008-3.318h3.496l1.008 3.318c.016.049.039.072.113.072h1.734c.072 0 .078-.025.062-.076-.014-.05-3.083-9.741-3.494-11.04zm-2.618 6.318l1.447-5.25 1.447 5.25H3.226z"></path></svg><span>简体中文</span></span></a><ul class="dropdown__menu"><li><a href="/blog" target="_self" rel="noopener noreferrer" class="dropdown__link">English</a></li><li><a href="/fr/blog" target="_self" rel="noopener noreferrer" class="dropdown__link">Français</a></li><li><a href="/ko/blog" target="_self" rel="noopener noreferrer" class="dropdown__link">한국어</a></li><li><a href="/zh-hans/blog" target="_self" rel="noopener noreferrer" class="dropdown__link dropdown__link--active">简体中文</a></li></ul></div><div class="toggle_iYfV toggle_2i4l toggleDisabled_xj38"><div class="toggleTrack_t-f2" role="button" tabindex="-1"><div class="toggleTrackCheck_mk7D"><span class="toggleIcon_pHJ9">🌜</span></div><div class="toggleTrackX_dm8H"><span class="toggleIcon_pHJ9">🌞</span></div><div class="toggleTrackThumb_W6To"></div></div><input type="checkbox" class="toggleScreenReader_h9qa" aria-label="Switch between dark and light mode"></div><div class="searchBox_Utm0"><button type="button" class="DocSearch DocSearch-Button" aria-label="搜索"><span class="DocSearch-Button-Container"><svg width="20" height="20" class="DocSearch-Search-Icon" viewBox="0 0 20 20"><path d="M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z" stroke="currentColor" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round"></path></svg><span class="DocSearch-Button-Placeholder">搜索</span></span><span class="DocSearch-Button-Keys"></span></button></div></div></div><div role="presentation" class="navbar-sidebar__backdrop"></div></nav><div class="main-wrapper blog-wrapper blog-list-page"><div class="container margin-vert--lg"><div class="row"><aside class="col col--3"><nav class="sidebar_q+wC thin-scrollbar" aria-label="最近博文导航"><div class="sidebarItemTitle_9G5K margin-bottom--md">Recent posts</div><ul class="sidebarItemList_6T4b"><li class="sidebarItem_cjdF"><a class="sidebarItemLink_zyXk" href="/zh-hans/blog/2023/03/01/recoil-0.7.7-release">Recoil 0.7.7</a></li><li class="sidebarItem_cjdF"><a class="sidebarItemLink_zyXk" href="/zh-hans/blog/2022/10/11/recoil-0.7.6-release">Recoil 0.7.6</a></li><li class="sidebarItem_cjdF"><a class="sidebarItemLink_zyXk" href="/zh-hans/blog/2022/10/06/recoil-sync-0.2.0-release">Recoil Sync 0.2</a></li><li class="sidebarItem_cjdF"><a class="sidebarItemLink_zyXk" href="/zh-hans/blog/2022/08/18/refine-0.1.1-release">Refine 0.1.1</a></li><li class="sidebarItem_cjdF"><a class="sidebarItemLink_zyXk" href="/zh-hans/blog/2022/08/11/recoil-0.7.5-release">Recoil 0.7.5</a></li></ul></nav></aside><main class="col col--7" itemscope="" itemtype="http://schema.org/Blog"><article class="margin-bottom--xl" itemprop="blogPost" itemscope="" itemtype="http://schema.org/BlogPosting"><header><h2 class="blogPostTitle_d4p0" itemprop="headline"><a itemprop="url" href="/zh-hans/blog/2023/03/01/recoil-0.7.7-release">Recoil 0.7.7</a></h2><div class="blogPostData_-Im+ margin-vert--md"><time datetime="2023-03-01T00:00:00.000Z" itemprop="datePublished">2023年3月1日</time> · <!-- -->阅读时间为 1 分钟</div></header><div class="markdown" itemprop="articleBody"><ul><li>Fix potential unhandled promise rejection in <code>useRecoilCallback()</code> (<a href="https://github.com/facebookexperimental/Recoil/pull/2075" target="_blank" rel="noopener noreferrer">#2075</a>)</li><li>Add OSS support for <a href="/zh-hans/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" target="_blank" rel="noopener noreferrer">#2078</a>)</li><li>Fix resolving suspense of async selectors used with SSR (<a href="https://github.com/facebookexperimental/Recoil/pull/2073" target="_blank" rel="noopener noreferrer">#2073</a>, <a href="https://github.com/facebookexperimental/Recoil/pull/1960" target="_blank" rel="noopener noreferrer">#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" target="_blank" rel="noopener noreferrer">#2082</a>, <a href="https://github.com/facebookexperimental/Recoil/pull/2086" target="_blank" rel="noopener noreferrer">#2086</a>)</li></ul></div></article><article class="margin-bottom--xl" itemprop="blogPost" itemscope="" itemtype="http://schema.org/BlogPosting"><header><h2 class="blogPostTitle_d4p0" itemprop="headline"><a itemprop="url" href="/zh-hans/blog/2022/10/11/recoil-0.7.6-release">Recoil 0.7.6</a></h2><div class="blogPostData_-Im+ margin-vert--md"><time datetime="2022-10-11T00:00:00.000Z" itemprop="datePublished">2022年10月11日</time> · <!-- -->阅读时间为 1 分钟</div></header><div class="markdown" itemprop="articleBody"><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" target="_blank" rel="noopener noreferrer">#733</a>, <a href="https://github.com/facebookexperimental/Recoil/pull/2020" target="_blank" rel="noopener noreferrer">#2020</a>, <a href="https://github.com/facebookexperimental/Recoil/pull/2046" target="_blank" rel="noopener noreferrer">#2046</a>)</p><ul><li>Import <a href="/zh-hans/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" target="_blank" rel="noopener noreferrer">#2001</a>, <a href="https://github.com/facebookexperimental/Recoil/pull/2010" target="_blank" rel="noopener noreferrer">#2010</a>)</p></li></ul></div></article><article class="margin-bottom--xl" itemprop="blogPost" itemscope="" itemtype="http://schema.org/BlogPosting"><header><h2 class="blogPostTitle_d4p0" itemprop="headline"><a itemprop="url" href="/zh-hans/blog/2022/10/06/recoil-sync-0.2.0-release">Recoil Sync 0.2</a></h2><div class="blogPostData_-Im+ margin-vert--md"><time datetime="2022-10-06T00:00:00.000Z" itemprop="datePublished">2022年10月6日</time> · <!-- -->阅读时间为 1 分钟</div></header><div class="markdown" itemprop="articleBody"><ul><li>Export <code>updateItems()</code> for the <a href="https://recoiljs.org/docs/recoil-sync/api/RecoilSync#listen-interface" target="_blank" rel="noopener noreferrer"><code>listen</code></a> prop callback in <a href="https://recoiljs.org/docs/recoil-sync/api/RecoilSync" target="_blank" rel="noopener noreferrer"><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" target="_blank" rel="noopener noreferrer">#2017</a>, <a href="https://github.com/facebookexperimental/Recoil/pull/2035" target="_blank" rel="noopener noreferrer">#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" target="_blank" rel="noopener noreferrer">#1900</a>, <a href="https://github.com/facebookexperimental/Recoil/pull/1976" target="_blank" rel="noopener noreferrer">#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" target="_blank" rel="noopener noreferrer"><code>&lt;RecoilURLSyncTransit&gt;</code></a>. (<a href="https://github.com/facebookexperimental/Recoil/pull/2044" target="_blank" rel="noopener noreferrer">#2044</a>)</li></ul></div></article><article class="margin-bottom--xl" itemprop="blogPost" itemscope="" itemtype="http://schema.org/BlogPosting"><header><h2 class="blogPostTitle_d4p0" itemprop="headline"><a itemprop="url" href="/zh-hans/blog/2022/08/18/refine-0.1.1-release">Refine 0.1.1</a></h2><div class="blogPostData_-Im+ margin-vert--md"><time datetime="2022-08-18T00:00:00.000Z" itemprop="datePublished">2022年8月18日</time> · <!-- -->阅读时间为 1 分钟</div></header><div class="markdown" itemprop="articleBody"><ul><li>Rename <code>boolean()</code> export to <a href="/zh-hans/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" target="_blank" rel="noopener noreferrer">#1922</a>, <a href="https://github.com/facebookexperimental/Recoil/pull/1962" target="_blank" rel="noopener noreferrer">#1962</a>, <a href="https://github.com/facebookexperimental/Recoil/pull/1971" target="_blank" rel="noopener noreferrer">#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" target="_blank" rel="noopener noreferrer">#1931</a>)</li><li>Export <code>Path</code> class for custom checkers. (<a href="https://github.com/facebookexperimental/Recoil/pull/1950" target="_blank" rel="noopener noreferrer">#1950</a>, <a href="https://github.com/facebookexperimental/Recoil/pull/1956" target="_blank" rel="noopener noreferrer">#1956</a>)</li><li>Extend the failure message of <a href="/zh-hans/docs/refine/api/Advanced_Checkers#union"><code>union()</code></a> and <a href="/zh-hans/docs/refine/api/Advanced_Checkers#or"><code>or()</code></a> with each type. (<a href="https://github.com/facebookexperimental/Recoil/pull/1961" target="_blank" rel="noopener noreferrer">#1961</a>)</li></ul></div></article><article class="margin-bottom--xl" itemprop="blogPost" itemscope="" itemtype="http://schema.org/BlogPosting"><header><h2 class="blogPostTitle_d4p0" itemprop="headline"><a itemprop="url" href="/zh-hans/blog/2022/08/11/recoil-0.7.5-release">Recoil 0.7.5</a></h2><div class="blogPostData_-Im+ margin-vert--md"><time datetime="2022-08-11T00:00:00.000Z" itemprop="datePublished">2022年8月11日</time> · <!-- -->阅读时间为 1 分钟</div></header><div class="markdown" itemprop="articleBody"><ul><li>Fix <code>useRecoilSnapshot()</code> with React&#x27;s Fast Refresh during development (<a href="https://github.com/facebookexperimental/Recoil/pull/1891" target="_blank" rel="noopener noreferrer">#1891</a>)</li><li>Fix <code>useRecoilSnapshot()</code> and <a href="https://recoiljs.org/docs/recoil-sync/introduction" target="_blank" rel="noopener noreferrer"><code>recoil-sync</code></a> with changed browser behavior starting with Chrome v104 (<a href="https://github.com/facebookexperimental/Recoil/pull/1943" target="_blank" rel="noopener noreferrer">#1943</a>, <a href="https://github.com/facebookexperimental/Recoil/pull/1936" target="_blank" rel="noopener noreferrer">#1936</a>)</li></ul></div></article><article class="margin-bottom--xl" itemprop="blogPost" itemscope="" itemtype="http://schema.org/BlogPosting"><header><h2 class="blogPostTitle_d4p0" itemprop="headline"><a itemprop="url" href="/zh-hans/blog/2022/06/21/recoil-sync-0.1.0-release">Recoil Sync 0.1</a></h2><div class="blogPostData_-Im+ margin-vert--md"><time datetime="2022-06-21T00:00:00.000Z" itemprop="datePublished">2022年6月21日</time> · <!-- -->阅读时间为 3 分钟</div></header><div class="markdown" itemprop="articleBody"><p>Initial open source release for the <a href="https://www.npmjs.com/package/recoil-sync" target="_blank" rel="noopener noreferrer"><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="/zh-hans/docs/guides/asynchronous-data-queries">asynchronous data queries</a> can be implemented via selectors or <code>useEffect()</code>, or <a href="/zh-hans/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="/zh-hans/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="/zh-hans/docs/recoil-sync/url-persistence">syncing with the browser URL</a>.</p><hr><p>The basic idea is that a <a href="/zh-hans/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="/zh-hans/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="/zh-hans/docs/recoil-sync/url-persistence"><code>&lt;RecoilURLSyncJSON&gt;</code></a>, <a href="/zh-hans/docs/recoil-sync/implement-store">make your own</a>, or even sync different groups of atoms with different stores.</p><h2 class="anchor anchorWithStickyNavbar_y2LR" id="example">Example<a class="hash-link" href="#example" title="链接到头部的标签">​</a></h2><h3 class="anchor anchorWithStickyNavbar_y2LR" id="url-persistence">URL Persistence<a class="hash-link" href="#url-persistence" title="链接到头部的标签">​</a></h3><p>Here is a simple example <a href="/zh-hans/docs/recoil-sync/url-persistence">syncing an atom with the browser URL</a>:</p><div class="codeBlockContainer_J+bg language-jsx theme-code-block"><div class="codeBlockContent_csEI jsx"><pre tabindex="0" class="prism-code language-jsx codeBlock_rtdJ thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_1zSZ"><span class="token-line" style="color:#bfc7d5"><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> currentUserState </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> atom</span><span class="token tag punctuation" style="color:rgb(199, 146, 234)">&lt;</span><span class="token tag" style="color:rgb(255, 85, 114)">number</span><span class="token tag punctuation" style="color:rgb(199, 146, 234)">&gt;</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#bfc7d5"><span class="token plain"> key</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">&#x27;CurrentUser&#x27;</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#bfc7d5"><span class="token plain"> </span><span class="token keyword" style="font-style:italic">default</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#bfc7d5"><span class="token plain"> effects</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#bfc7d5"><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">syncEffect</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> refine</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">number</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#bfc7d5"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></span></code></pre><button type="button" aria-label="复制代码" class="copyButton_M3SB clean-btn">复制</button></div></div><p>Then, at the root of your application, simply include <a href="/zh-hans/docs/recoil-sync/api/RecoilURLSyncJSON"><code>&lt;RecoilURLSyncJSON&gt;</code></a> to sync all of those tagged atoms with the URL</p><div class="codeBlockContainer_J+bg language-jsx theme-code-block"><div class="codeBlockContent_csEI jsx"><pre tabindex="0" class="prism-code language-jsx codeBlock_rtdJ thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_1zSZ"><span class="token-line" style="color:#bfc7d5"><span class="token keyword" style="font-style:italic">function</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">MyApp</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#bfc7d5"><span class="token plain"> </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#bfc7d5"><span class="token plain"> </span><span class="token tag punctuation" style="color:rgb(199, 146, 234)">&lt;</span><span class="token tag class-name" style="color:rgb(255, 203, 107)">RecoilRoot</span><span class="token tag punctuation" style="color:rgb(199, 146, 234)">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#bfc7d5"><span class="token plain"> </span><span class="token tag punctuation" style="color:rgb(199, 146, 234)">&lt;</span><span class="token tag class-name" style="color:rgb(255, 203, 107)">RecoilURLSyncJSON</span><span class="token tag" style="color:rgb(255, 85, 114)"> </span><span class="token tag attr-name" style="color:rgb(255, 203, 107)">location</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:rgb(199, 146, 234)">=</span><span class="token tag script language-javascript punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token tag script language-javascript punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token tag script language-javascript" style="color:rgb(255, 85, 114)">part</span><span class="token tag script language-javascript operator" style="color:rgb(137, 221, 255)">:</span><span class="token tag script language-javascript" style="color:rgb(255, 85, 114)"> </span><span class="token tag script language-javascript string" style="color:rgb(195, 232, 141)">&#x27;queryParams&#x27;</span><span class="token tag script language-javascript punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token tag script language-javascript punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token tag punctuation" style="color:rgb(199, 146, 234)">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#bfc7d5"><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#bfc7d5"><span class="token plain"> </span><span class="token tag punctuation" style="color:rgb(199, 146, 234)">&lt;/</span><span class="token tag class-name" style="color:rgb(255, 203, 107)">RecoilURLSyncJSON</span><span class="token tag punctuation" style="color:rgb(199, 146, 234)">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#bfc7d5"><span class="token plain"> </span><span class="token tag punctuation" style="color:rgb(199, 146, 234)">&lt;/</span><span class="token tag class-name" style="color:rgb(255, 203, 107)">RecoilRoot</span><span class="token tag punctuation" style="color:rgb(199, 146, 234)">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#bfc7d5"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><br></span></code></pre><button type="button" aria-label="复制代码" class="copyButton_M3SB clean-btn">复制</button></div></div><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="/zh-hans/docs/recoil-sync/sync-effect">Sync Effect</a>, <a href="/zh-hans/docs/recoil-sync/implement-store">Store Implementation</a>, and <a href="/zh-hans/docs/recoil-sync/url-persistence">URL Persistence</a> guides.</p></div></article><article class="margin-bottom--xl" itemprop="blogPost" itemscope="" itemtype="http://schema.org/BlogPosting"><header><h2 class="blogPostTitle_d4p0" itemprop="headline"><a itemprop="url" href="/zh-hans/blog/2022/06/21/refine-0.1.0-release">Refine 0.1</a></h2><div class="blogPostData_-Im+ margin-vert--md"><time datetime="2022-06-21T00:00:00.000Z" itemprop="datePublished">2022年6月21日</time> · <!-- -->阅读时间为 2 分钟</div></header><div class="markdown" itemprop="articleBody"><p>Initial open source release for the <a href="https://www.npmjs.com/package/@recoiljs/refine" target="_blank" rel="noopener noreferrer"><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="/zh-hans/docs/refine/api/Utilities">Utilities</a> and <a href="/zh-hans/docs/refine/api/Checkers">Checkers</a>.</p><p>The <a href="/zh-hans/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="/zh-hans/docs/recoil-sync/introduction"><code>recoil-sync</code> docs</a> for more details.</p><h3 class="anchor anchorWithStickyNavbar_y2LR" id="why-would-i-want-to-use-refine">Why would I want to use Refine?<a class="hash-link" href="#why-would-i-want-to-use-refine" title="链接到头部的标签">​</a></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="/zh-hans/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="/zh-hans/docs/refine/Introduction#backward-compatible-example">upgrade from previous versions</a>.</li></ul><h3 class="anchor anchorWithStickyNavbar_y2LR" id="type-refinement-example">Type Refinement Example<a class="hash-link" href="#type-refinement-example" title="链接到头部的标签">​</a></h3><p>Coerce unknown types to a strongly typed variable. <a href="/zh-hans/docs/refine/api/Utilities#assertion"><code>assertion()</code></a> will throw if the input doesn&#x27;t match the expected type while <a href="/zh-hans/docs/refine/api/Utilities#coercion"><code>coercion()</code></a> will return <code>null</code>.</p><div class="codeBlockContainer_J+bg language-jsx theme-code-block"><div class="codeBlockContent_csEI jsx"><pre tabindex="0" class="prism-code language-jsx codeBlock_rtdJ thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_1zSZ"><span class="token-line" style="color:#bfc7d5"><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> myObjectChecker </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">object</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#bfc7d5"><span class="token plain"> numberProperty</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">number</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#bfc7d5"><span class="token plain"> stringProperty</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">optional</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token function" style="color:rgb(130, 170, 255)">string</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#bfc7d5"><span class="token plain"> arrayProperty</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">array</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token function" style="color:rgb(130, 170, 255)">number</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> myObjectAssertion </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">assertion</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">myObjectChecker</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> myObject</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> CheckerReturnType</span><span class="token tag punctuation" style="color:rgb(199, 146, 234)">&lt;</span><span class="token tag" style="color:rgb(255, 85, 114)">myObjectChecker</span><span class="token tag punctuation" style="color:rgb(199, 146, 234)">&gt;</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">myObjectAssertion</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#bfc7d5"><span class="token plain"> numberProperty</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">123</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#bfc7d5"><span class="token plain"> stringProperty</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">&#x27;hello&#x27;</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#bfc7d5"><span class="token plain"> arrayProperty</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token number" style="color:rgb(247, 140, 108)">1</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">2</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">3</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></span></code></pre><button type="button" aria-label="复制代码" class="copyButton_M3SB clean-btn">复制</button></div></div><h3 class="anchor anchorWithStickyNavbar_y2LR" id="backward-compatible-example">Backward Compatible Example<a class="hash-link" href="#backward-compatible-example" title="链接到头部的标签">​</a></h3><p>Using <a href="/zh-hans/docs/refine/api/Advanced_Checkers#match"><code>match()</code></a> and <a href="/zh-hans/docs/refine/api/Advanced_Checkers#asType"><code>asType()</code></a> you can upgrade from previous types to the latest version.</p><div class="codeBlockContainer_J+bg language-jsx theme-code-block"><div class="codeBlockContent_csEI jsx"><pre tabindex="0" class="prism-code language-jsx codeBlock_rtdJ thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_1zSZ"><span class="token-line" style="color:#bfc7d5"><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> myChecker</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> Checker</span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;</span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain">str</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> string</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token operator" style="color:rgb(137, 221, 255)">&gt;</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">match</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#bfc7d5"><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">object</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain">str</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">string</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#bfc7d5"><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">asType</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token function" style="color:rgb(130, 170, 255)">string</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token parameter">str</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain">str</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> str</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#bfc7d5"><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">asType</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token function" style="color:rgb(130, 170, 255)">number</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token parameter">num</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain">str</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">String</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">num</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> obj1</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain">str</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> string</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">coercion</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token function" style="color:rgb(130, 170, 255)">myChecker</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain">str</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">&#x27;hello&#x27;</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> obj2</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain">str</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> string</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">coercion</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token function" style="color:rgb(130, 170, 255)">myChecker</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string" style="color:rgb(195, 232, 141)">&#x27;hello&#x27;</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> obj3</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain">str</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> string</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">coercion</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token function" style="color:rgb(130, 170, 255)">myChecker</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token number" style="color:rgb(247, 140, 108)">123</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></span></code></pre><button type="button" aria-label="复制代码" class="copyButton_M3SB clean-btn">复制</button></div></div><h3 class="anchor anchorWithStickyNavbar_y2LR" id="json-parser-example">JSON Parser Example<a class="hash-link" href="#json-parser-example" title="链接到头部的标签">​</a></h3><p>Refine wraps <code>JSON</code> to provide a built-in strongly typed parser.</p><div class="codeBlockContainer_J+bg language-jsx theme-code-block"><div class="codeBlockContent_csEI jsx"><pre tabindex="0" class="prism-code language-jsx codeBlock_rtdJ thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_1zSZ"><span class="token-line" style="color:#bfc7d5"><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> myParser </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">jsonParser</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#bfc7d5"><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">array</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token function" style="color:rgb(130, 170, 255)">object</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain">num</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">number</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> result </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">myParser</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string" style="color:rgb(195, 232, 141)">&#x27;[{&quot;num&quot;: 1}, {&quot;num&quot;: 2}]&#x27;</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">result </span><span class="token operator" style="color:rgb(137, 221, 255)">!=</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">null</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#bfc7d5"><span class="token plain"> </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">// we can now access values in num typesafe way</span><span class="token plain"></span><br></span><span class="token-line" style="color:#bfc7d5"><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">assert</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">result</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token number" style="color:rgb(247, 140, 108)">0</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">num </span><span class="token operator" style="color:rgb(137, 221, 255)">===</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">1</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">else</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#bfc7d5"><span class="token plain"> </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">// value failed to match parser spec</span><span class="token plain"></span><br></span><span class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><br></span></code></pre><button type="button" aria-label="复制代码" class="copyButton_M3SB clean-btn">复制</button></div></div></div></article><article class="margin-bottom--xl" itemprop="blogPost" itemscope="" itemtype="http://schema.org/BlogPosting"><header><h2 class="blogPostTitle_d4p0" itemprop="headline"><a itemprop="url" href="/zh-hans/blog/2022/06/20/recoil-0.7.4-release">Recoil 0.7.4</a></h2><div class="blogPostData_-Im+ margin-vert--md"><time datetime="2022-06-20T00:00:00.000Z" itemprop="datePublished">2022年6月20日</time> · <!-- -->阅读时间为 1 分钟</div></header><div class="markdown" itemprop="articleBody"><ul><li>Fix missing flow types (<a href="https://github.com/facebookexperimental/Recoil/pull/1857" target="_blank" rel="noopener noreferrer">#1857</a>)</li><li>Cleanup memory leak when using atoms with selector defaults. (<a href="https://github.com/facebookexperimental/Recoil/pull/1821" target="_blank" rel="noopener noreferrer">#1821</a>, <a href="https://github.com/facebookexperimental/Recoil/pull/1840" target="_blank" rel="noopener noreferrer">#1840</a>, <a href="https://github.com/facebookexperimental/Recoil/pull/1844" target="_blank" rel="noopener noreferrer">#1844</a>)</li></ul></div></article><article class="margin-bottom--xl" itemprop="blogPost" itemscope="" itemtype="http://schema.org/BlogPosting"><header><h2 class="blogPostTitle_d4p0" itemprop="headline"><a itemprop="url" href="/zh-hans/blog/2022/06/02/recoil-relay-0.1.0-release">Recoil Relay 0.1</a></h2><div class="blogPostData_-Im+ margin-vert--md"><time datetime="2022-06-02T00:00:00.000Z" itemprop="datePublished">2022年6月2日</time> · <!-- -->阅读时间为 1 分钟</div></header><div class="markdown" itemprop="articleBody"><p>Initial open source release for the <a href="/zh-hans/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/" target="_blank" rel="noopener noreferrer">GraphQL</a> with the <a href="https://relay.dev" target="_blank" rel="noopener noreferrer">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 class="anchor anchorWithStickyNavbar_y2LR" id="example">Example<a class="hash-link" href="#example" title="链接到头部的标签">​</a></h3><p>A GraphQL query is as simple as defining a <a href="/zh-hans/docs/recoil-relay/graphql-queries">GraphQL selector</a>:</p><div class="codeBlockContainer_J+bg language-jsx theme-code-block"><div class="codeBlockContent_csEI jsx"><pre tabindex="0" class="prism-code language-jsx codeBlock_rtdJ thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_1zSZ"><span class="token-line" style="color:#bfc7d5"><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> userNameQuery </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">graphQLSelector</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#bfc7d5"><span class="token plain"> key</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">&#x27;UserName&#x27;</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#bfc7d5"><span class="token plain"> environment</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> myEnvironment</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#bfc7d5"><span class="token plain"> query</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> graphql</span><span class="token template-string template-punctuation string" style="color:rgb(195, 232, 141)">`</span><span class="token template-string string" style="color:rgb(195, 232, 141)"></span><br></span><span class="token-line" style="color:#bfc7d5"><span class="token template-string string" style="color:rgb(195, 232, 141)"> query UserQuery($id: ID!) {</span><br></span><span class="token-line" style="color:#bfc7d5"><span class="token template-string string" style="color:rgb(195, 232, 141)"> user(id: $id) {</span><br></span><span class="token-line" style="color:#bfc7d5"><span class="token template-string string" style="color:rgb(195, 232, 141)"> name</span><br></span><span class="token-line" style="color:#bfc7d5"><span class="token template-string string" style="color:rgb(195, 232, 141)"> }</span><br></span><span class="token-line" style="color:#bfc7d5"><span class="token template-string string" style="color:rgb(195, 232, 141)"> }</span><br></span><span class="token-line" style="color:#bfc7d5"><span class="token template-string string" style="color:rgb(195, 232, 141)"> </span><span class="token template-string template-punctuation string" style="color:rgb(195, 232, 141)">`</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#bfc7d5"><span class="token plain"> </span><span class="token function-variable function" style="color:rgb(130, 170, 255)">variables</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token parameter punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token parameter">get</span><span class="token parameter punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain">id</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">get</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">currentIDAtom</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#bfc7d5"><span class="token plain"> </span><span class="token function-variable function" style="color:rgb(130, 170, 255)">mapResponse</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token parameter">data</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=&gt;</span><span class="token plain"> data</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">user</span><span class="token operator" style="color:rgb(137, 221, 255)">?.</span><span class="token plain">name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></span></code></pre><button type="button" aria-label="复制代码" class="copyButton_M3SB clean-btn">复制</button></div></div><p>Then use it like any other Recoil <a href="/zh-hans/docs/introduction/core-concepts#selectors">selector</a>:</p><div class="codeBlockContainer_J+bg language-jsx theme-code-block"><div class="codeBlockContent_csEI jsx"><pre tabindex="0" class="prism-code language-jsx codeBlock_rtdJ thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_1zSZ"><span class="token-line" style="color:#bfc7d5"><span class="token keyword" style="font-style:italic">function</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">MyComponent</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#bfc7d5"><span class="token plain"> </span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> userName </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">useRecoilValue</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">userNameQuery</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#bfc7d5"><span class="token plain"> </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> </span><span class="token tag punctuation" style="color:rgb(199, 146, 234)">&lt;</span><span class="token tag" style="color:rgb(255, 85, 114)">span</span><span class="token tag punctuation" style="color:rgb(199, 146, 234)">&gt;</span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain">userName</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token tag punctuation" style="color:rgb(199, 146, 234)">&lt;/</span><span class="token tag" style="color:rgb(255, 85, 114)">span</span><span class="token tag punctuation" style="color:rgb(199, 146, 234)">&gt;</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><br></span></code></pre><button type="button" aria-label="复制代码" class="copyButton_M3SB clean-btn">复制</button></div></div></div></article><article class="margin-bottom--xl" itemprop="blogPost" itemscope="" itemtype="http://schema.org/BlogPosting"><header><h2 class="blogPostTitle_d4p0" itemprop="headline"><a itemprop="url" href="/zh-hans/blog/2022/06/01/recoil-0.7.3-release">Recoil 0.7.3</a></h2><div class="blogPostData_-Im+ margin-vert--md"><time datetime="2022-06-01T00:00:00.000Z" itemprop="datePublished">2022年6月1日</time> · <!-- -->阅读时间为 1 分钟</div></header><div class="markdown" itemprop="articleBody"><ul><li>Enable atoms and selectors to be used in <a href="/zh-hans/docs/api-reference/utils/selectorFamily#parameter-type">family parameters</a> (<a href="https://github.com/facebookexperimental/Recoil/pull/1740" target="_blank" rel="noopener noreferrer">#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="/zh-hans/docs/recoil-relay/graphql-queries#pre-fetch-graphql">pre-fetch pattern for GraphQL</a>. (<a href="https://github.com/facebookexperimental/Recoil/pull/1744" target="_blank" rel="noopener noreferrer">#1744</a>)</li><li>Atom effects can initialize or set atoms to wrapped values (<a href="https://github.com/facebookexperimental/Recoil/pull/1681" target="_blank" rel="noopener noreferrer">#1681</a>)</li></ul></div></article><nav class="pagination-nav" aria-label="博客文章列表的分页"><div class="pagination-nav__item"></div><div class="pagination-nav__item pagination-nav__item--next"><a class="pagination-nav__link" href="/zh-hans/blog/page/2"><div class="pagination-nav__label">下一篇<!-- --> <!-- -->»</div></a></div></nav></main></div></div></div><footer class="footer footer--dark"><div class="container container-fluid"><div class="row footer__links"><div class="col footer__col"><div class="footer__title">学习</div><ul class="footer__items"><li class="footer__item"><a class="footer__link-item" href="/zh-hans/docs/introduction/getting-started">快速上手</a></li><li class="footer__item"><a class="footer__link-item" href="/zh-hans/docs/introduction/core-concepts">核心概念</a></li></ul></div><div class="col footer__col"><div class="footer__title">社区</div><ul class="footer__items"><li class="footer__item"><a href="https://twitter.com/recoiljs" target="_blank" rel="noopener noreferrer" class="footer__link-item"><span>推特<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_wgqa"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"></path></svg></span></a></li></ul></div><div class="col footer__col"><div class="footer__title">更多</div><ul class="footer__items"><li class="footer__item"><a href="https://github.com/facebookexperimental/Recoil" target="_blank" rel="noopener noreferrer" class="footer__link-item"><span>GitHub<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_wgqa"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"></path></svg></span></a></li></ul></div><div class="col footer__col"><div class="footer__title">法律</div><ul class="footer__items"><li class="footer__item"><a href="https://opensource.facebook.com/legal/privacy/" target="_blank" rel="noreferrer noopener" class="footer__link-item"><span>隐私<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_wgqa"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"></path></svg></span></a></li><li class="footer__item"><a href="https://opensource.facebook.com/legal/terms/" target="_blank" rel="noreferrer noopener" class="footer__link-item"><span>条款<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_wgqa"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"></path></svg></span></a></li></ul></div></div><div class="footer__bottom text--center"><div class="margin-bottom--sm"><a href="https://opensource.facebook.com" target="_blank" rel="noopener noreferrer" class="footerLogoLink_SRtH"><img src="/zh-hans/img/oss_logo.png" alt="Facebook Open Source Logo" class="themedImage_TMUO themedImage--light_4Vu1 footer__logo"><img src="/zh-hans/img/oss_logo.png" alt="Facebook Open Source Logo" class="themedImage_TMUO themedImage--dark_uzRr footer__logo"></a></div><div class="footer__copyright">版权所有 © 2021 Facebook, Inc. 使用 Docusaurus 构建.</div></div></div></footer></div> <script src="/zh-hans/assets/js/runtime~main.8e652302.js"></script> <script src="/zh-hans/assets/js/main.f671ce00.js"></script> </body> </html>

Pages: 1 2 3 4 5 6 7 8 9 10