mirror of
https://github.com/callstack/react-native-testing-library.git
synced 2026-09-18 23:09:04 +08:00
346 lines
119 KiB
HTML
346 lines
119 KiB
HTML
<!doctype html>
|
|
<html lang="en">
|
|
<head><meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<title>Network Requests - React Native Testing Library</title>
|
|
<script>{;const saved = localStorage.getItem('rspress-theme-appearance');const preferDark = window.matchMedia('(prefers-color-scheme: dark)').matches;const isDark = !saved || saved === 'auto' ? preferDark : saved === 'dark';document.documentElement.classList.toggle('dark', isDark);document.documentElement.classList.toggle('rp-dark', isDark);document.documentElement.style.colorScheme = isDark ? 'dark' : 'light';}</script>
|
|
<link href="/react-native-testing-library/static/css/styles.89185f7811.css" rel="stylesheet">
|
|
<script defer src="/react-native-testing-library/static/js/styles.68ae892e1a.js"></script>
|
|
<script defer src="/react-native-testing-library/static/js/lib-react.49604bf759.js"></script>
|
|
<script defer src="/react-native-testing-library/static/js/lib-router.a0df4de158.js"></script>
|
|
<script defer src="/react-native-testing-library/static/js/2482.4740a55c68.js"></script>
|
|
<script defer src="/react-native-testing-library/static/js/index.b6e4c985e3.js"></script>
|
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
<meta name="generator" content="Rspress v2.0.9">
|
|
<meta property="og:url" content="https://oss.callstack.com/react-native-testing-library/">
|
|
<meta property="og:type" content="website">
|
|
<meta property="og:title" content="Network Requests - React Native Testing Library">
|
|
<meta property="og:description" content="Helps you to write better tests with less effort.">
|
|
<link rel="icon" href="/react-native-testing-library/logo-light.png">
|
|
<meta name="description" content="Helps you to write better tests with less effort."></head>
|
|
|
|
<body>
|
|
<div id="__rspress_root"><link rel="preload" as="image" href="/react-native-testing-library/img/logo-light.svg"/><link rel="preload" as="image" href="/react-native-testing-library/img/logo-dark.svg"/><link rel="preload" as="image" href="/react-native-testing-library/static/image/abstract-atom.4eca0300ff.avif"/><header class="rp-nav"><div class="rp-nav__left"><div class="rp-nav__title"><a href="/react-native-testing-library/" class="rp-nav__title__link rp-link"><div class="rp-nav__title__logo"><img src="/react-native-testing-library/img/logo-light.svg" alt="logo" id="logo" class="rspress-logo rp-nav__title__logo-image rp-nav__title__logo-image--light"/><img src="/react-native-testing-library/img/logo-dark.svg" alt="logo" id="logo" class="rspress-logo rp-nav__title__logo-image rp-nav__title__logo-image--dark"/></div></a></div></div><div class="rp-nav__right"><button class="rp-search-button"><div class="rp-search-button__content"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none" viewBox="0 0 16 16" class="rp-search-button__icon"><path fill="#838289" d="M14.667 14.666h-1.333v-1.333h1.332zm-1.333-1.333H12V12h1.333zm-4-1.333H4v-1.334h5.334zM12 12h-1.335v-1.334h1.335zm-8-1.334H2.665V9.333H4zm6.665 0H9.334V9.333h1.332zm-8-1.333H1.335V4h1.333zm9.335 0h-1.335V4h1.335zM4 4H2.665V2.666H4zm6.665 0H9.334V2.666h1.332zM9.334 2.666H4V1.333h5.334z"></path></svg><span class="rp-search-button__word">Search</span></div><div class="rp-search-button__hotkey" style="opacity:0"><span></span><span>K</span></div></button><div class="rp-search-button--mobile"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none" viewBox="0 0 16 16"><path fill="#838289" d="M14.667 14.666h-1.333v-1.333h1.332zm-1.333-1.333H12V12h1.333zm-4-1.333H4v-1.334h5.334zM12 12h-1.335v-1.334h1.335zm-8-1.334H2.665V9.333H4zm6.665 0H9.334V9.333h1.332zm-8-1.333H1.335V4h1.333zm9.335 0h-1.335V4h1.335zM4 4H2.665V2.666H4zm6.665 0H9.334V2.666h1.332zM9.334 2.666H4V1.333h5.334z"></path></svg></div><ul class="rp-nav-menu rp-nav-menu--right"><li class="rp-nav-menu__item"><a href="/react-native-testing-library/docs/start/intro" class="rp-nav-menu__item__container rp-link">Docs</a></li><li class="rp-nav-menu__item rp-nav-menu__item--active"><a href="/react-native-testing-library/cookbook/" class="rp-nav-menu__item__container rp-link">Cookbook</a></li><li class="rp-nav-menu__item"><a href="https://github.com/callstack/react-native-testing-library/tree/main/examples" target="_blank" class="rp-nav-menu__item__container rp-link">Examples</a></li></ul><div class="rp-nav__others"><div class="rp-nav-menu__divider"></div><li class="rp-nav-menu__item"><div class="rp-nav-menu__item__container">14.x<svg xmlns="http://www.w3.org/2000/svg" width="12" height="13" viewBox="0 0 12 13" class="rp-nav-menu__item__icon"><path fill="currentColor" d="M6.5 8.5h1v1h-1v1h-1v-1h-1v-1h1v-6h1zm-2 0h-1v-1h1zm4 0h-1v-1h1zm-5-2v1h-1v-1zm6 1h-1v-1h1z"></path></svg></div><ul class="rp-hover-group rp-hover-group--hidden rp-hover-group--center"><li class="rp-hover-group__item" style="padding-left:8px" data-depth="0"><a href="/react-native-testing-library/12.x/cookbook/advanced/network-requests" class="rp-hover-group__item__link rp-link" aria-label="12.x">12.x</a></li><li class="rp-hover-group__item" style="padding-left:8px" data-depth="0"><a href="/react-native-testing-library/13.x/cookbook/advanced/network-requests" class="rp-hover-group__item__link rp-link" aria-label="13.x">13.x</a></li><li class="rp-hover-group__item rp-hover-group__item--active" style="padding-left:8px" data-depth="0"><a href="/react-native-testing-library/advanced/network-requests" class="rp-hover-group__item__link rp-link" aria-label="14.x">14.x</a></li></ul></li><div role="button" tabindex="0" class="rspress-nav-appearance"><div class="rp-p-1 rp-border rp-border-solid rp-border-gray-300 rp-text-gray-400 rp-cursor-pointer rp-rounded-md rp-transition-all rp-duration-300 rp-w-7 rp-h-7"><svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" fill="currentColor" viewBox="0 0 24 24"><path fill="currentColor" d="M18 22H8v-2h10zM8 20H6v-2h2zm12 0h-2v-2h2zM6 18H4v-2h2zm16 0h-2v-4h-2v-2h2v-2h2zM4 16H2V6h2zm14 0h-6v-2h6zm-6-2h-2v-2h2zm-2-2H8V6h2zM6 6H4V4h2zm8-2h-2v2h-2V4H6V2h8z"></path></svg></div></div><div class="rp-social-links"><a href="https://github.com/callstack/react-native-testing-library" target="_blank" rel="noopener noreferrer" class="rp-social-links__item"><div class="rp-social-links__icon"><div class="rp-social-links__icon"><svg xmlns="http://www.w3.org/2000/svg" width="100%" viewBox="0 0 24 24"><path fill="currentColor" d="M12 .297c-6.63 0-12 5.373-12 12c0 5.303 3.438 9.8 8.205 11.385c.6.113.82-.258.82-.577c0-.285-.01-1.04-.015-2.04c-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729c1.205.084 1.838 1.236 1.838 1.236c1.07 1.835 2.809 1.305 3.495.998c.108-.776.417-1.305.76-1.605c-2.665-.3-5.466-1.332-5.466-5.93c0-1.31.465-2.38 1.235-3.22c-.135-.303-.54-1.523.105-3.176c0 0 1.005-.322 3.3 1.23c.96-.267 1.98-.399 3-.405c1.02.006 2.04.138 3 .405c2.28-1.552 3.285-1.23 3.285-1.23c.645 1.653.24 2.873.12 3.176c.765.84 1.23 1.91 1.23 3.22c0 4.61-2.805 5.625-5.475 5.92c.42.36.81 1.096.81 2.22c0 1.606-.015 2.896-.015 3.286c0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/></svg></div></div></a><ul class="rp-hover-group rp-hover-group--hidden rp-hover-group--right"></ul></div></div><button aria-label="mobile hamburger" class="rp-nav-hamburger rp-nav-hamburger__sm"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24"><path fill="#838289" fill-rule="evenodd" d="M1 9h6v6H1zm2 2v2h2v-2zm6-2h6v6H9zm2 2v2h2v-2zm6-2h6v6h-6zm2 2v2h2v-2z" clip-rule="evenodd"></path></svg></button><button aria-label="mobile hamburger" class="rp-nav-hamburger rp-nav-hamburger__md"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24"><path fill="#838289" fill-rule="evenodd" d="M1 9h6v6H1zm2 2v2h2v-2zm6-2h6v6H9zm2 2v2h2v-2zm6-2h6v6h-6zm2 2v2h2v-2z" clip-rule="evenodd"></path></svg><ul class="rp-hover-group rp-hover-group--hidden rp-hover-group--right"><div class="rp-nav-menu__others-mobile__container"><div class="rp-nav-hamburger__md__hover-group"><div class="rp-nav-screen-appearance"><div class="rp-nav-screen-appearance__left">Theme</div><div class="rp-nav-screen-appearance__right"></div></div><li class="rp-nav-menu__item"><div class="rp-nav-menu__item__container">14.x<svg xmlns="http://www.w3.org/2000/svg" width="12" height="13" viewBox="0 0 12 13" class="rp-nav-menu__item__icon"><path fill="currentColor" d="M6.5 8.5h1v1h-1v1h-1v-1h-1v-1h1v-6h1zm-2 0h-1v-1h1zm4 0h-1v-1h1zm-5-2v1h-1v-1zm6 1h-1v-1h1z"></path></svg></div><ul class="rp-hover-group rp-hover-group--hidden rp-hover-group--center"><li class="rp-hover-group__item" style="padding-left:8px" data-depth="0"><a href="/react-native-testing-library/12.x/cookbook/advanced/network-requests" class="rp-hover-group__item__link rp-link" aria-label="12.x">12.x</a></li><li class="rp-hover-group__item" style="padding-left:8px" data-depth="0"><a href="/react-native-testing-library/13.x/cookbook/advanced/network-requests" class="rp-hover-group__item__link rp-link" aria-label="13.x">13.x</a></li><li class="rp-hover-group__item rp-hover-group__item--active" style="padding-left:8px" data-depth="0"><a href="/react-native-testing-library/advanced/network-requests" class="rp-hover-group__item__link rp-link" aria-label="14.x">14.x</a></li></ul></li><div class="rp-nav-screen-divider"></div><div class="rp-social-links"><a href="https://github.com/callstack/react-native-testing-library" target="_blank" rel="noopener noreferrer" class="rp-social-links__item"><div class="rp-social-links__icon"><div class="rp-social-links__icon"><svg xmlns="http://www.w3.org/2000/svg" width="100%" viewBox="0 0 24 24"><path fill="currentColor" d="M12 .297c-6.63 0-12 5.373-12 12c0 5.303 3.438 9.8 8.205 11.385c.6.113.82-.258.82-.577c0-.285-.01-1.04-.015-2.04c-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729c1.205.084 1.838 1.236 1.838 1.236c1.07 1.835 2.809 1.305 3.495.998c.108-.776.417-1.305.76-1.605c-2.665-.3-5.466-1.332-5.466-5.93c0-1.31.465-2.38 1.235-3.22c-.135-.303-.54-1.523.105-3.176c0 0 1.005-.322 3.3 1.23c.96-.267 1.98-.399 3-.405c1.02.006 2.04.138 3 .405c2.28-1.552 3.285-1.23 3.285-1.23c.645 1.653.24 2.873.12 3.176c.765.84 1.23 1.91 1.23 3.22c0 4.61-2.805 5.625-5.475 5.92c.42.36.81 1.096.81 2.22c0 1.606-.015 2.896-.015 3.286c0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/></svg></div></div></a><ul class="rp-hover-group rp-hover-group--hidden rp-hover-group--right"></ul></div></div></div></ul></button></div></header><div class="rp-doc-layout__menu"><div class="rp-sidebar-menu"><button type="button" class="rp-sidebar-menu__left"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24"><path fill="#838289" d="M20 18H4v-2h16zm0-5H4v-2h16zm0-5H4V6h16z"></path></svg><span>Menu</span></button><button type="button" class="rp-sidebar-menu__right"><span class="rp-sidebar-menu__right__text">Contents</span><svg width="14" height="14" class="rp-progress-circle"><circle cx="7" cy="7" r="6" stroke-linecap="round" fill="none" stroke="var(--rp-c-divider-light)" stroke-width="2"></circle><circle cx="7" cy="7" r="6" stroke-linecap="round" fill="none" stroke="var(--rp-c-brand)" stroke-width="2" stroke-dasharray="37.69911184307752" stroke-dashoffset="37.69911184307752" transform="rotate(-90 7 7)" style="transition:stroke-dashoffset 0.3s"></circle></svg><svg xmlns="http://www.w3.org/2000/svg" width="12" height="13" fill="none" viewBox="0 0 12 13" class="rp-sidebar-menu__right__icon" style="transform:rotate(0deg);transition:transform 0.2s ease-out"><path fill="#BCBBC2" d="M6.5 4.5h1v-1h-1v-1h-1v1h-1v1h1v6h1zm-2 0h-1v1h1zm4 0h-1v1h1zm-5 2v-1h-1v1zm6-1h-1v1h1z"></path></svg></button></div></div><div class="rp-doc-layout__container"><aside class="rp-doc-layout__sidebar rp-scrollbar"><a href="/react-native-testing-library/cookbook/" class="rp-sidebar-item rp-link" style="padding-left:12px" data-depth="0"><div class="rp-sidebar-item__left"><span>Cookbook</span></div><div class="rp-sidebar-item__right"></div></a><div class="rp-sidebar-item rp-sidebar-group" style="padding-left:12px" data-depth="0"><div class="rp-sidebar-item__left"><span>Basic Recipes</span></div><div class="rp-sidebar-item__right"><div style="cursor:pointer;transition:transform 0.2s ease-out;transform:rotate(90deg)"><svg xmlns="http://www.w3.org/2000/svg" width="12" height="13" fill="none" viewBox="0 0 12 13"><path fill="#BCBBC2" d="M6.5 4.5h1v-1h-1v-1h-1v1h-1v1h1v6h1zm-2 0h-1v1h1zm4 0h-1v1h1zm-5 2v-1h-1v1zm6-1h-1v1h1z"></path></svg></div></div></div><div style="display:grid;grid-template-rows:1fr;transition:grid-template-rows 0.2s ease-out"><div style="overflow:hidden"><a href="/react-native-testing-library/cookbook/basics/async-events" class="rp-sidebar-item rp-sidebar-item--group-item rp-link" style="padding-left:calc(12px * 1 + 12px)" data-depth="1"><div class="rp-sidebar-item__left"><span>Async Events</span></div><div class="rp-sidebar-item__right"></div></a><a href="/react-native-testing-library/cookbook/basics/custom-render" class="rp-sidebar-item rp-sidebar-item--group-item rp-link" style="padding-left:calc(12px * 1 + 12px)" data-depth="1"><div class="rp-sidebar-item__left"><span>Custom Render</span></div><div class="rp-sidebar-item__right"></div></a></div></div><div class="rp-sidebar-item rp-sidebar-group" style="padding-left:12px" data-depth="0"><div class="rp-sidebar-item__left"><span>Advanced Recipes</span></div><div class="rp-sidebar-item__right"><div style="cursor:pointer;transition:transform 0.2s ease-out;transform:rotate(90deg)"><svg xmlns="http://www.w3.org/2000/svg" width="12" height="13" fill="none" viewBox="0 0 12 13"><path fill="#BCBBC2" d="M6.5 4.5h1v-1h-1v-1h-1v1h-1v1h1v6h1zm-2 0h-1v1h1zm4 0h-1v1h1zm-5 2v-1h-1v1zm6-1h-1v1h1z"></path></svg></div></div></div><div style="display:grid;grid-template-rows:1fr;transition:grid-template-rows 0.2s ease-out"><div style="overflow:hidden"><a href="/react-native-testing-library/cookbook/advanced/network-requests" class="rp-sidebar-item rp-sidebar-item--active rp-sidebar-item--group-item rp-link" style="padding-left:calc(12px * 1 + 12px)" data-depth="1"><div class="rp-sidebar-item__left"><span>Network Requests</span></div><div class="rp-sidebar-item__right"></div></a></div></div><div class="rp-sidebar-item rp-sidebar-group" style="padding-left:12px" data-depth="0"><div class="rp-sidebar-item__left"><span>State Management Recipes</span></div><div class="rp-sidebar-item__right"><div style="cursor:pointer;transition:transform 0.2s ease-out;transform:rotate(90deg)"><svg xmlns="http://www.w3.org/2000/svg" width="12" height="13" fill="none" viewBox="0 0 12 13"><path fill="#BCBBC2" d="M6.5 4.5h1v-1h-1v-1h-1v1h-1v1h1v6h1zm-2 0h-1v1h1zm4 0h-1v1h1zm-5 2v-1h-1v1zm6-1h-1v1h1z"></path></svg></div></div></div><div style="display:grid;grid-template-rows:1fr;transition:grid-template-rows 0.2s ease-out"><div style="overflow:hidden"><a href="/react-native-testing-library/cookbook/state-management/jotai" class="rp-sidebar-item rp-sidebar-item--group-item rp-link" style="padding-left:calc(12px * 1 + 12px)" data-depth="1"><div class="rp-sidebar-item__left"><span>Jotai</span></div><div class="rp-sidebar-item__right"></div></a></div></div></aside><div class="rp-doc-layout__doc"><main class="rp-doc-layout__doc-container"><div class="rp-doc rspress-doc"><!--$--><h1 class="rp-toc-include" id="network-requests"><a href="#network-requests" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Network Requests<!-- --> </h1><div class="rp-not-doc rp-llms-container"><button class="rp-not-doc rp-llms-button rp-llms-copy-button"><div class="rp-llms-copy-button__icon-wrapper"><svg xmlns="http://www.w3.org/2000/svg" width="271" height="271" viewBox="0 0 271 271" class="rp-llms-copy-button__icon-success"><path fill="currentColor" d="M112.687 203.223H90.174v-22.514h22.512v-22.514h22.512v22.514h-22.511zm-22.514-22.514H67.66v-22.514h22.513zm-22.514-22.514H45.146v-22.512H67.66zm90.054 0h-22.514v-22.512h22.514zm22.514-22.512h-22.514v-22.514h22.514zm22.513-22.514h-22.513V90.655h22.513zm22.514-22.514H202.74V68.143h22.514z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="272" height="272" viewBox="0 0 272 272" class="rp-llms-copy-button__icon-copy"><path fill="currentColor" fill-rule="evenodd" d="M45.883 23.368h123.823v22.514H68.396v146.336H45.883zm45.026 45.027H225.99v180.107H90.91zm22.514 22.513v135.08h90.053V90.908z" clip-rule="evenodd"></path></svg></div><span>Copy Markdown</span></button><button class="rp-llms-button rp-llms-view-options__trigger "><svg xmlns="http://www.w3.org/2000/svg" width="12" height="13" viewBox="0 0 12 13" class="rp-llms-view-options__arrow "><path fill="currentColor" d="M6.5 8.5h1v1h-1v1h-1v-1h-1v-1h1v-6h1zm-2 0h-1v-1h1zm4 0h-1v-1h1zm-5-2v1h-1v-1zm6 1h-1v-1h1z"></path></svg></button></div>
|
|
<h2 class="rp-toc-include" id="introduction"><a href="#introduction" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Introduction</h2>
|
|
<p>Mocking network requests is an essential part of testing React Native applications. By mocking
|
|
network
|
|
requests, you can control the data that is returned from the server and test how your application
|
|
behaves in different scenarios, such as when the request is successful or when it fails.</p>
|
|
<p>In this guide, we will show you how to mock network requests and guard your test suits from unwanted
|
|
and unmocked/unhandled network requests</p>
|
|
<div class="rp-callout rp-callout--info"><div class="rp-callout__title">Info</div><div class="rp-callout__content"><p>
|
|
To simulate a real-world scenario, we will use the <a href="https://randomuser.me/" target="_blank" rel="noopener noreferrer" class="rp-link">Random User Generator API</a> that provides random user data.</p></div></div>
|
|
<h2 class="rp-toc-include" id="phonebook-example"><a href="#phonebook-example" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Phonebook Example</h2>
|
|
<p>Let's assume we have a simple phonebook application that
|
|
uses <a href="https://reactnative.dev/docs/network#using-fetch" target="_blank" rel="noopener noreferrer" class="rp-link"><code>fetch</code></a> for fetching Data from a server.
|
|
In our case, we have a list of contacts and favorites that we want to display in our application.</p>
|
|
<p>This is how the root of the application looks like:</p>
|
|
<div class="rp-codeblock language-tsx"><div class="rp-codeblock__title">network-requests/Phonebook.tsx</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="tsx" data-title="network-requests/Phonebook.tsx"><code><span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> React</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> { useEffect</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> useState } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> 'react'</span><span style="color:var(--shiki-foreground)">;</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { Text } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> 'react-native'</span><span style="color:var(--shiki-foreground)">;</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { User } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> './types'</span><span style="color:var(--shiki-foreground)">;</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> ContactsList </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> './components/ContactsList'</span><span style="color:var(--shiki-foreground)">;</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> FavoritesList </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> './components/FavoritesList'</span><span style="color:var(--shiki-foreground)">;</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> getAllContacts </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> './api/getAllContacts'</span><span style="color:var(--shiki-foreground)">;</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> getAllFavorites </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> './api/getAllFavorites'</span><span style="color:var(--shiki-foreground)">;</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-foreground)"> () </span><span style="color:var(--shiki-token-keyword)">=></span><span style="color:var(--shiki-foreground)"> {</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> const</span><span style="color:var(--shiki-foreground)"> [</span><span style="color:var(--shiki-token-constant)">usersData</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-token-constant)"> setUsersData</span><span style="color:var(--shiki-foreground)">] </span><span style="color:var(--shiki-token-keyword)">=</span><span style="color:var(--shiki-token-function)"> useState</span><span style="color:var(--shiki-foreground)"><</span><span style="color:var(--shiki-token-function)">User</span><span style="color:var(--shiki-foreground)">[]>([]);</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> const</span><span style="color:var(--shiki-foreground)"> [</span><span style="color:var(--shiki-token-constant)">favoritesData</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-token-constant)"> setFavoritesData</span><span style="color:var(--shiki-foreground)">] </span><span style="color:var(--shiki-token-keyword)">=</span><span style="color:var(--shiki-token-function)"> useState</span><span style="color:var(--shiki-foreground)"><</span><span style="color:var(--shiki-token-function)">User</span><span style="color:var(--shiki-foreground)">[]>([]);</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> const</span><span style="color:var(--shiki-foreground)"> [</span><span style="color:var(--shiki-token-constant)">error</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-token-constant)"> setError</span><span style="color:var(--shiki-foreground)">] </span><span style="color:var(--shiki-token-keyword)">=</span><span style="color:var(--shiki-token-function)"> useState</span><span style="color:var(--shiki-foreground)"><</span><span style="color:var(--shiki-token-constant)">string</span><span style="color:var(--shiki-token-keyword)"> |</span><span style="color:var(--shiki-token-constant)"> null</span><span style="color:var(--shiki-foreground)">>(</span><span style="color:var(--shiki-token-constant)">null</span><span style="color:var(--shiki-foreground)">);</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)"> useEffect</span><span style="color:var(--shiki-foreground)">(() </span><span style="color:var(--shiki-token-keyword)">=></span><span style="color:var(--shiki-foreground)"> {</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> const</span><span style="color:var(--shiki-token-function)"> _getAllContacts</span><span style="color:var(--shiki-token-keyword)"> =</span><span style="color:var(--shiki-token-keyword)"> async</span><span style="color:var(--shiki-foreground)"> () </span><span style="color:var(--shiki-token-keyword)">=></span><span style="color:var(--shiki-foreground)"> {</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> const</span><span style="color:var(--shiki-token-constant)"> _data</span><span style="color:var(--shiki-token-keyword)"> =</span><span style="color:var(--shiki-token-keyword)"> await</span><span style="color:var(--shiki-token-function)"> getAllContacts</span><span style="color:var(--shiki-foreground)">();</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)"> setUsersData</span><span style="color:var(--shiki-foreground)">(_data);</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> };</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> const</span><span style="color:var(--shiki-token-function)"> _getAllFavorites</span><span style="color:var(--shiki-token-keyword)"> =</span><span style="color:var(--shiki-token-keyword)"> async</span><span style="color:var(--shiki-foreground)"> () </span><span style="color:var(--shiki-token-keyword)">=></span><span style="color:var(--shiki-foreground)"> {</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> const</span><span style="color:var(--shiki-token-constant)"> _data</span><span style="color:var(--shiki-token-keyword)"> =</span><span style="color:var(--shiki-token-keyword)"> await</span><span style="color:var(--shiki-token-function)"> getAllFavorites</span><span style="color:var(--shiki-foreground)">();</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)"> setFavoritesData</span><span style="color:var(--shiki-foreground)">(_data);</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> };</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> const</span><span style="color:var(--shiki-token-function)"> run</span><span style="color:var(--shiki-token-keyword)"> =</span><span style="color:var(--shiki-token-keyword)"> async</span><span style="color:var(--shiki-foreground)"> () </span><span style="color:var(--shiki-token-keyword)">=></span><span style="color:var(--shiki-foreground)"> {</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> try</span><span style="color:var(--shiki-foreground)"> {</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> await</span><span style="color:var(--shiki-token-constant)"> Promise</span><span style="color:var(--shiki-token-function)">.all</span><span style="color:var(--shiki-foreground)">([</span><span style="color:var(--shiki-token-function)">_getAllContacts</span><span style="color:var(--shiki-foreground)">()</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-token-function)"> _getAllFavorites</span><span style="color:var(--shiki-foreground)">()]);</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> } </span><span style="color:var(--shiki-token-keyword)">catch</span><span style="color:var(--shiki-foreground)"> (e) {</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> const</span><span style="color:var(--shiki-token-constant)"> message</span><span style="color:var(--shiki-token-keyword)"> =</span><span style="color:var(--shiki-token-function)"> isErrorWithMessage</span><span style="color:var(--shiki-foreground)">(e) </span><span style="color:var(--shiki-token-keyword)">?</span><span style="color:var(--shiki-token-constant)"> e</span><span style="color:var(--shiki-foreground)">.message </span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> 'Something went wrong'</span><span style="color:var(--shiki-foreground)">;</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)"> setError</span><span style="color:var(--shiki-foreground)">(message);</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> }</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> };</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> void</span><span style="color:var(--shiki-token-function)"> run</span><span style="color:var(--shiki-foreground)">();</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> }</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> []);</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> if</span><span style="color:var(--shiki-foreground)"> (error) {</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> return</span><span style="color:var(--shiki-foreground)"> <</span><span style="color:var(--shiki-token-constant)">Text</span><span style="color:var(--shiki-foreground)">>An error occurred: {error}</</span><span style="color:var(--shiki-token-constant)">Text</span><span style="color:var(--shiki-foreground)">>;</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> }</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> return</span><span style="color:var(--shiki-foreground)"> (</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> <></span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> <</span><span style="color:var(--shiki-token-constant)">FavoritesList</span><span style="color:var(--shiki-token-function)"> users</span><span style="color:var(--shiki-token-keyword)">=</span><span style="color:var(--shiki-foreground)">{favoritesData} /></span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> <</span><span style="color:var(--shiki-token-constant)">ContactsList</span><span style="color:var(--shiki-token-function)"> users</span><span style="color:var(--shiki-token-keyword)">=</span><span style="color:var(--shiki-foreground)">{usersData} /></span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> </></span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> );</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="Copy code"><svg xmlns="http://www.w3.org/2000/svg" width="272" height="272" viewBox="0 0 272 272" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" fill-rule="evenodd" d="M45.883 23.368h123.823v22.514H68.396v146.336H45.883zm45.026 45.027H225.99v180.107H90.91zm22.514 22.513v135.08h90.053V90.908z" clip-rule="evenodd"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="271" height="271" viewBox="0 0 271 271" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="M112.687 203.223H90.174v-22.514h22.512v-22.514h22.512v22.514h-22.511zm-22.514-22.514H67.66v-22.514h22.513zm-22.514-22.514H45.146v-22.512H67.66zm90.054 0h-22.514v-22.512h22.514zm22.514-22.512h-22.514v-22.514h22.514zm22.513-22.514h-22.513V90.655h22.513zm22.514-22.514H202.74V68.143h22.514z"></path></svg></button></div></div></div>
|
|
<p>We fetch the contacts from the server using the <code>getAllFavorites</code> function that utilizes <code>fetch</code>.</p>
|
|
<div class="rp-codeblock language-tsx"><div class="rp-codeblock__title">network-requests/api/getAllContacts.ts</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="tsx" data-title="network-requests/api/getAllContacts.ts"><code><span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { User } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> '../types'</span><span style="color:var(--shiki-foreground)">;</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-token-keyword)"> async</span><span style="color:var(--shiki-foreground)"> ()</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-function)"> Promise</span><span style="color:var(--shiki-foreground)"><</span><span style="color:var(--shiki-token-function)">User</span><span style="color:var(--shiki-foreground)">[]> </span><span style="color:var(--shiki-token-keyword)">=></span><span style="color:var(--shiki-foreground)"> {</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> const</span><span style="color:var(--shiki-token-constant)"> res</span><span style="color:var(--shiki-token-keyword)"> =</span><span style="color:var(--shiki-token-keyword)"> await</span><span style="color:var(--shiki-token-function)"> fetch</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">'https://randomuser.me/api/?results=25'</span><span style="color:var(--shiki-foreground)">);</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> if</span><span style="color:var(--shiki-foreground)"> (</span><span style="color:var(--shiki-token-keyword)">!</span><span style="color:var(--shiki-token-constant)">res</span><span style="color:var(--shiki-foreground)">.ok) {</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> throw</span><span style="color:var(--shiki-token-keyword)"> new</span><span style="color:var(--shiki-token-function)"> Error</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">`Error fetching contacts`</span><span style="color:var(--shiki-foreground)">);</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> }</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> const</span><span style="color:var(--shiki-token-constant)"> json</span><span style="color:var(--shiki-token-keyword)"> =</span><span style="color:var(--shiki-token-keyword)"> await</span><span style="color:var(--shiki-token-constant)"> res</span><span style="color:var(--shiki-token-function)">.json</span><span style="color:var(--shiki-foreground)">();</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> return</span><span style="color:var(--shiki-token-constant)"> json</span><span style="color:var(--shiki-foreground)">.results;</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="Copy code"><svg xmlns="http://www.w3.org/2000/svg" width="272" height="272" viewBox="0 0 272 272" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" fill-rule="evenodd" d="M45.883 23.368h123.823v22.514H68.396v146.336H45.883zm45.026 45.027H225.99v180.107H90.91zm22.514 22.513v135.08h90.053V90.908z" clip-rule="evenodd"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="271" height="271" viewBox="0 0 271 271" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="M112.687 203.223H90.174v-22.514h22.512v-22.514h22.512v22.514h-22.511zm-22.514-22.514H67.66v-22.514h22.513zm-22.514-22.514H45.146v-22.512H67.66zm90.054 0h-22.514v-22.512h22.514zm22.514-22.512h-22.514v-22.514h22.514zm22.513-22.514h-22.513V90.655h22.513zm22.514-22.514H202.74V68.143h22.514z"></path></svg></button></div></div></div>
|
|
<p>We have similar function for fetching the favorites, but this time limiting the results to 10.</p>
|
|
<div class="rp-codeblock language-tsx"><div class="rp-codeblock__title">network-requests/api/getAllFavorites.ts</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="tsx" data-title="network-requests/api/getAllFavorites.ts"><code><span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { User } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> '../types'</span><span style="color:var(--shiki-foreground)">;</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-token-keyword)"> async</span><span style="color:var(--shiki-foreground)"> ()</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-function)"> Promise</span><span style="color:var(--shiki-foreground)"><</span><span style="color:var(--shiki-token-function)">User</span><span style="color:var(--shiki-foreground)">[]> </span><span style="color:var(--shiki-token-keyword)">=></span><span style="color:var(--shiki-foreground)"> {</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> const</span><span style="color:var(--shiki-token-constant)"> res</span><span style="color:var(--shiki-token-keyword)"> =</span><span style="color:var(--shiki-token-keyword)"> await</span><span style="color:var(--shiki-token-function)"> fetch</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">'https://randomuser.me/api/?results=10'</span><span style="color:var(--shiki-foreground)">);</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> if</span><span style="color:var(--shiki-foreground)"> (</span><span style="color:var(--shiki-token-keyword)">!</span><span style="color:var(--shiki-token-constant)">res</span><span style="color:var(--shiki-foreground)">.ok) {</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> throw</span><span style="color:var(--shiki-token-keyword)"> new</span><span style="color:var(--shiki-token-function)"> Error</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">`Error fetching favorites`</span><span style="color:var(--shiki-foreground)">);</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> }</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> const</span><span style="color:var(--shiki-token-constant)"> json</span><span style="color:var(--shiki-token-keyword)"> =</span><span style="color:var(--shiki-token-keyword)"> await</span><span style="color:var(--shiki-token-constant)"> res</span><span style="color:var(--shiki-token-function)">.json</span><span style="color:var(--shiki-foreground)">();</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> return</span><span style="color:var(--shiki-token-constant)"> json</span><span style="color:var(--shiki-foreground)">.results;</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="Copy code"><svg xmlns="http://www.w3.org/2000/svg" width="272" height="272" viewBox="0 0 272 272" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" fill-rule="evenodd" d="M45.883 23.368h123.823v22.514H68.396v146.336H45.883zm45.026 45.027H225.99v180.107H90.91zm22.514 22.513v135.08h90.053V90.908z" clip-rule="evenodd"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="271" height="271" viewBox="0 0 271 271" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="M112.687 203.223H90.174v-22.514h22.512v-22.514h22.512v22.514h-22.511zm-22.514-22.514H67.66v-22.514h22.513zm-22.514-22.514H45.146v-22.512H67.66zm90.054 0h-22.514v-22.512h22.514zm22.514-22.512h-22.514v-22.514h22.514zm22.513-22.514h-22.513V90.655h22.513zm22.514-22.514H202.74V68.143h22.514z"></path></svg></button></div></div></div>
|
|
<p>Our <code>FavoritesList</code> component is a simple component that displays the list of favorite contacts and
|
|
their avatars horizontally.</p>
|
|
<div class="rp-codeblock language-tsx"><div class="rp-codeblock__title">network-requests/components/FavoritesList.tsx</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="tsx" data-title="network-requests/components/FavoritesList.tsx"><code><span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> {FlatList</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> Image</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> StyleSheet</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> Text</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> View} </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> 'react-native'</span><span style="color:var(--shiki-foreground)">;</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> React</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> {useCallback} </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> 'react'</span><span style="color:var(--shiki-foreground)">;</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-token-keyword)"> type</span><span style="color:var(--shiki-foreground)"> {ListRenderItem} </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> '@react-native/virtualized-lists'</span><span style="color:var(--shiki-foreground)">;</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> {User} </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> '../types'</span><span style="color:var(--shiki-foreground)">;</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-foreground)"> ({users}</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> { users</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-function)"> User</span><span style="color:var(--shiki-foreground)">[] }) </span><span style="color:var(--shiki-token-keyword)">=></span><span style="color:var(--shiki-foreground)"> {</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> const</span><span style="color:var(--shiki-token-constant)"> renderItem</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-function)"> ListRenderItem</span><span style="color:var(--shiki-foreground)"><</span><span style="color:var(--shiki-token-function)">User</span><span style="color:var(--shiki-foreground)">> </span><span style="color:var(--shiki-token-keyword)">=</span><span style="color:var(--shiki-token-function)"> useCallback</span><span style="color:var(--shiki-foreground)">(({item: {picture}}) </span><span style="color:var(--shiki-token-keyword)">=></span><span style="color:var(--shiki-foreground)"> {</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> return</span><span style="color:var(--shiki-foreground)"> (</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> <</span><span style="color:var(--shiki-token-constant)">View</span><span style="color:var(--shiki-token-function)"> style</span><span style="color:var(--shiki-token-keyword)">=</span><span style="color:var(--shiki-foreground)">{</span><span style="color:var(--shiki-token-constant)">styles</span><span style="color:var(--shiki-foreground)">.userContainer}></span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> <</span><span style="color:var(--shiki-token-constant)">Image</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)"> source</span><span style="color:var(--shiki-token-keyword)">=</span><span style="color:var(--shiki-foreground)">{{uri</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> picture</span><span style="color:var(--shiki-foreground)">.thumbnail}}</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)"> style</span><span style="color:var(--shiki-token-keyword)">=</span><span style="color:var(--shiki-foreground)">{</span><span style="color:var(--shiki-token-constant)">styles</span><span style="color:var(--shiki-foreground)">.userImage}</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)"> accessibilityLabel</span><span style="color:var(--shiki-token-keyword)">=</span><span style="color:var(--shiki-foreground)">{</span><span style="color:var(--shiki-token-string-expression)">'favorite-contact-avatar'</span><span style="color:var(--shiki-foreground)">}</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> /></span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> </</span><span style="color:var(--shiki-token-constant)">View</span><span style="color:var(--shiki-foreground)">></span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> );</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> }</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> []);</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> if</span><span style="color:var(--shiki-foreground)"> (</span><span style="color:var(--shiki-token-constant)">users</span><span style="color:var(--shiki-foreground)">.</span><span style="color:var(--shiki-token-constant)">length</span><span style="color:var(--shiki-token-keyword)"> ===</span><span style="color:var(--shiki-token-constant)"> 0</span><span style="color:var(--shiki-foreground)">) </span><span style="color:var(--shiki-token-keyword)">return</span><span style="color:var(--shiki-foreground)"> (</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> <</span><span style="color:var(--shiki-token-constant)">View</span><span style="color:var(--shiki-token-function)"> style</span><span style="color:var(--shiki-token-keyword)">=</span><span style="color:var(--shiki-foreground)">{</span><span style="color:var(--shiki-token-constant)">styles</span><span style="color:var(--shiki-foreground)">.loaderContainer}></span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> <</span><span style="color:var(--shiki-token-constant)">Text</span><span style="color:var(--shiki-foreground)">>Figuring out your favorites...</</span><span style="color:var(--shiki-token-constant)">Text</span><span style="color:var(--shiki-foreground)">></span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> </</span><span style="color:var(--shiki-token-constant)">View</span><span style="color:var(--shiki-foreground)">></span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> );</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> return</span><span style="color:var(--shiki-foreground)"> (</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> <</span><span style="color:var(--shiki-token-constant)">View</span><span style="color:var(--shiki-token-function)"> style</span><span style="color:var(--shiki-token-keyword)">=</span><span style="color:var(--shiki-foreground)">{</span><span style="color:var(--shiki-token-constant)">styles</span><span style="color:var(--shiki-foreground)">.outerContainer}></span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> <</span><span style="color:var(--shiki-token-constant)">Text</span><span style="color:var(--shiki-foreground)">>⭐My Favorites</</span><span style="color:var(--shiki-token-constant)">Text</span><span style="color:var(--shiki-foreground)">></span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> <</span><span style="color:var(--shiki-token-constant)">FlatList</span><span style="color:var(--shiki-foreground)"><</span><span style="color:var(--shiki-token-function)">User</span><span style="color:var(--shiki-foreground)">></span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)"> horizontal</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)"> showsHorizontalScrollIndicator</span><span style="color:var(--shiki-token-keyword)">=</span><span style="color:var(--shiki-foreground)">{</span><span style="color:var(--shiki-token-constant)">false</span><span style="color:var(--shiki-foreground)">}</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)"> data</span><span style="color:var(--shiki-token-keyword)">=</span><span style="color:var(--shiki-foreground)">{users}</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)"> renderItem</span><span style="color:var(--shiki-token-keyword)">=</span><span style="color:var(--shiki-foreground)">{renderItem}</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)"> keyExtractor</span><span style="color:var(--shiki-token-keyword)">=</span><span style="color:var(--shiki-foreground)">{(item</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> index) </span><span style="color:var(--shiki-token-keyword)">=></span><span style="color:var(--shiki-token-string-expression)"> `</span><span style="color:var(--shiki-token-keyword)">${</span><span style="color:var(--shiki-foreground)">index</span><span style="color:var(--shiki-token-keyword)">}</span><span style="color:var(--shiki-token-string-expression)">-</span><span style="color:var(--shiki-token-keyword)">${</span><span style="color:var(--shiki-token-constant)">item</span><span style="color:var(--shiki-foreground)">.</span><span style="color:var(--shiki-token-constant)">id</span><span style="color:var(--shiki-foreground)">.value</span><span style="color:var(--shiki-token-keyword)">}</span><span style="color:var(--shiki-token-string-expression)">`</span><span style="color:var(--shiki-foreground)">}</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> /></span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> </</span><span style="color:var(--shiki-token-constant)">View</span><span style="color:var(--shiki-foreground)">></span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> );</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)">// Looking for styles?</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)">// Check examples/cookbook/app/advanced/components/FavoritesList.tsx</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)">const</span><span style="color:var(--shiki-token-constant)"> styles</span><span style="color:var(--shiki-token-keyword)"> =</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)">...</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="Copy code"><svg xmlns="http://www.w3.org/2000/svg" width="272" height="272" viewBox="0 0 272 272" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" fill-rule="evenodd" d="M45.883 23.368h123.823v22.514H68.396v146.336H45.883zm45.026 45.027H225.99v180.107H90.91zm22.514 22.513v135.08h90.053V90.908z" clip-rule="evenodd"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="271" height="271" viewBox="0 0 271 271" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="M112.687 203.223H90.174v-22.514h22.512v-22.514h22.512v22.514h-22.511zm-22.514-22.514H67.66v-22.514h22.513zm-22.514-22.514H45.146v-22.512H67.66zm90.054 0h-22.514v-22.512h22.514zm22.514-22.512h-22.514v-22.514h22.514zm22.513-22.514h-22.513V90.655h22.513zm22.514-22.514H202.74V68.143h22.514z"></path></svg></button></div></div></div>
|
|
<p>Our <code>ContactsList</code> component is similar to the <code>FavoritesList</code> component, but it displays the list
|
|
of
|
|
all contacts vertically.</p>
|
|
<div class="rp-codeblock language-tsx"><div class="rp-codeblock__title">network-requests/components/ContactsList.tsx</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="tsx" data-title="network-requests/components/ContactsList.tsx"><code><span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { FlatList</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> Image</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> StyleSheet</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> Text</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> View } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> 'react-native'</span><span style="color:var(--shiki-foreground)">;</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> React</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> { useCallback } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> 'react'</span><span style="color:var(--shiki-foreground)">;</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-token-keyword)"> type</span><span style="color:var(--shiki-foreground)"> { ListRenderItem } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> '@react-native/virtualized-lists'</span><span style="color:var(--shiki-foreground)">;</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { User } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> '../types'</span><span style="color:var(--shiki-foreground)">;</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)">export</span><span style="color:var(--shiki-token-keyword)"> default</span><span style="color:var(--shiki-foreground)"> ({ users }</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> { users</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-function)"> User</span><span style="color:var(--shiki-foreground)">[] }) </span><span style="color:var(--shiki-token-keyword)">=></span><span style="color:var(--shiki-foreground)"> {</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> const</span><span style="color:var(--shiki-token-constant)"> renderItem</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-function)"> ListRenderItem</span><span style="color:var(--shiki-foreground)"><</span><span style="color:var(--shiki-token-function)">User</span><span style="color:var(--shiki-foreground)">> </span><span style="color:var(--shiki-token-keyword)">=</span><span style="color:var(--shiki-token-function)"> useCallback</span><span style="color:var(--shiki-foreground)">(</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> ({ item: { name</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> email</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> picture</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> cell }</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> index }) </span><span style="color:var(--shiki-token-keyword)">=></span><span style="color:var(--shiki-foreground)"> {</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> const</span><span style="color:var(--shiki-foreground)"> { </span><span style="color:var(--shiki-token-constant)">title</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-token-constant)"> first</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-token-constant)"> last</span><span style="color:var(--shiki-foreground)"> } </span><span style="color:var(--shiki-token-keyword)">=</span><span style="color:var(--shiki-foreground)"> name;</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> const</span><span style="color:var(--shiki-token-constant)"> backgroundColor</span><span style="color:var(--shiki-token-keyword)"> =</span><span style="color:var(--shiki-foreground)"> index </span><span style="color:var(--shiki-token-keyword)">%</span><span style="color:var(--shiki-token-constant)"> 2</span><span style="color:var(--shiki-token-keyword)"> ===</span><span style="color:var(--shiki-token-constant)"> 0</span><span style="color:var(--shiki-token-keyword)"> ?</span><span style="color:var(--shiki-token-string-expression)"> '#f9f9f9'</span><span style="color:var(--shiki-token-keyword)"> :</span><span style="color:var(--shiki-token-string-expression)"> '#fff'</span><span style="color:var(--shiki-foreground)">;</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> return</span><span style="color:var(--shiki-foreground)"> (</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> <</span><span style="color:var(--shiki-token-constant)">View</span><span style="color:var(--shiki-token-function)"> style</span><span style="color:var(--shiki-token-keyword)">=</span><span style="color:var(--shiki-foreground)">{[{ backgroundColor }</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-token-constant)"> styles</span><span style="color:var(--shiki-foreground)">.userContainer]}></span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> <</span><span style="color:var(--shiki-token-constant)">Image</span><span style="color:var(--shiki-token-function)"> source</span><span style="color:var(--shiki-token-keyword)">=</span><span style="color:var(--shiki-foreground)">{{ uri</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> picture</span><span style="color:var(--shiki-foreground)">.thumbnail }} </span><span style="color:var(--shiki-token-function)">style</span><span style="color:var(--shiki-token-keyword)">=</span><span style="color:var(--shiki-foreground)">{</span><span style="color:var(--shiki-token-constant)">styles</span><span style="color:var(--shiki-foreground)">.userImage} /></span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> <</span><span style="color:var(--shiki-token-constant)">View</span><span style="color:var(--shiki-foreground)">></span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> <</span><span style="color:var(--shiki-token-constant)">Text</span><span style="color:var(--shiki-foreground)">></span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> Name: {title} {first} {last}</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> </</span><span style="color:var(--shiki-token-constant)">Text</span><span style="color:var(--shiki-foreground)">></span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> <</span><span style="color:var(--shiki-token-constant)">Text</span><span style="color:var(--shiki-foreground)">>Email: {email}</</span><span style="color:var(--shiki-token-constant)">Text</span><span style="color:var(--shiki-foreground)">></span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> <</span><span style="color:var(--shiki-token-constant)">Text</span><span style="color:var(--shiki-foreground)">>Mobile: {cell}</</span><span style="color:var(--shiki-token-constant)">Text</span><span style="color:var(--shiki-foreground)">></span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> </</span><span style="color:var(--shiki-token-constant)">View</span><span style="color:var(--shiki-foreground)">></span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> </</span><span style="color:var(--shiki-token-constant)">View</span><span style="color:var(--shiki-foreground)">></span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> );</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> []</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> );</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> if</span><span style="color:var(--shiki-foreground)"> (</span><span style="color:var(--shiki-token-constant)">users</span><span style="color:var(--shiki-foreground)">.</span><span style="color:var(--shiki-token-constant)">length</span><span style="color:var(--shiki-token-keyword)"> ===</span><span style="color:var(--shiki-token-constant)"> 0</span><span style="color:var(--shiki-foreground)">) </span><span style="color:var(--shiki-token-keyword)">return</span><span style="color:var(--shiki-foreground)"> <</span><span style="color:var(--shiki-token-constant)">FullScreenLoader</span><span style="color:var(--shiki-foreground)"> />;</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> return</span><span style="color:var(--shiki-foreground)"> (</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> <</span><span style="color:var(--shiki-token-constant)">View</span><span style="color:var(--shiki-foreground)">></span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> <</span><span style="color:var(--shiki-token-constant)">FlatList</span><span style="color:var(--shiki-foreground)"><</span><span style="color:var(--shiki-token-function)">User</span><span style="color:var(--shiki-foreground)">></span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)"> data</span><span style="color:var(--shiki-token-keyword)">=</span><span style="color:var(--shiki-foreground)">{users}</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)"> renderItem</span><span style="color:var(--shiki-token-keyword)">=</span><span style="color:var(--shiki-foreground)">{renderItem}</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)"> keyExtractor</span><span style="color:var(--shiki-token-keyword)">=</span><span style="color:var(--shiki-foreground)">{(item</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> index) </span><span style="color:var(--shiki-token-keyword)">=></span><span style="color:var(--shiki-token-string-expression)"> `</span><span style="color:var(--shiki-token-keyword)">${</span><span style="color:var(--shiki-foreground)">index</span><span style="color:var(--shiki-token-keyword)">}</span><span style="color:var(--shiki-token-string-expression)">-</span><span style="color:var(--shiki-token-keyword)">${</span><span style="color:var(--shiki-token-constant)">item</span><span style="color:var(--shiki-foreground)">.</span><span style="color:var(--shiki-token-constant)">id</span><span style="color:var(--shiki-foreground)">.value</span><span style="color:var(--shiki-token-keyword)">}</span><span style="color:var(--shiki-token-string-expression)">`</span><span style="color:var(--shiki-foreground)">}</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> /></span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> </</span><span style="color:var(--shiki-token-constant)">View</span><span style="color:var(--shiki-foreground)">></span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> );</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)">// Looking for styles or FullScreenLoader component?</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)">// Check examples/cookbook/app/advanced/components/ContactsList.tsx</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)">const</span><span style="color:var(--shiki-token-function)"> FullScreenLoader</span><span style="color:var(--shiki-token-keyword)"> =</span><span style="color:var(--shiki-foreground)"> () </span><span style="color:var(--shiki-token-keyword)">=></span><span style="color:var(--shiki-token-keyword)"> ...</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)">const</span><span style="color:var(--shiki-token-constant)"> styles</span><span style="color:var(--shiki-token-keyword)"> =</span><span style="color:var(--shiki-token-keyword)"> ...</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="Copy code"><svg xmlns="http://www.w3.org/2000/svg" width="272" height="272" viewBox="0 0 272 272" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" fill-rule="evenodd" d="M45.883 23.368h123.823v22.514H68.396v146.336H45.883zm45.026 45.027H225.99v180.107H90.91zm22.514 22.513v135.08h90.053V90.908z" clip-rule="evenodd"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="271" height="271" viewBox="0 0 271 271" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="M112.687 203.223H90.174v-22.514h22.512v-22.514h22.512v22.514h-22.511zm-22.514-22.514H67.66v-22.514h22.513zm-22.514-22.514H45.146v-22.512H67.66zm90.054 0h-22.514v-22.512h22.514zm22.514-22.512h-22.514v-22.514h22.514zm22.513-22.514h-22.513V90.655h22.513zm22.514-22.514H202.74V68.143h22.514z"></path></svg></button></div></div></div>
|
|
<h2 class="rp-toc-include" id="start-testing-with-a-simple-test"><a href="#start-testing-with-a-simple-test" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Start testing with a simple test</h2>
|
|
<p>In our initial test we would like to test if the <code>PhoneBook</code> component renders the <code>FavoritesList</code>
|
|
and <code>ContactsList</code> components correctly.
|
|
We will need to mock the network requests and their corresponding responses to ensure that the component behaves as
|
|
expected. To mock the network requests we will use <a href="https://mswjs.io/docs/getting-started" target="_blank" rel="noopener noreferrer" class="rp-link">MSW (Mock Service Worker)</a>.</p>
|
|
<div class="rp-callout rp-callout--note"><div class="rp-callout__title">Note</div><div class="rp-callout__content"><p>
|
|
We recommend using the Mock Service Worker (MSW) library to declaratively mock API communication in your tests instead of stubbing <code>fetch</code>, or relying on third-party adapters.</p></div></div>
|
|
<div class="rp-callout rp-callout--info"><div class="rp-callout__title">Info</div><div class="rp-callout__content"><p>
|
|
You can install MSW by running <code>npm install msw --save-dev</code> or <code>yarn add msw --dev</code>.
|
|
More info regarding installation can be found in <a href="https://mswjs.io/docs/getting-started#step-1-install" target="_blank" rel="noopener noreferrer" class="rp-link">MSW's getting started guide</a>.</p><p>Please make sure you're also aware of <a href="https://mswjs.io/docs/integrations/react-native" target="_blank" rel="noopener noreferrer" class="rp-link">MSW's setup guide</a>.
|
|
Please be minded that the MSW's setup guide is potentially incomplete and might contain discrepancies/missing pieces.</p></div></div>
|
|
<div class="rp-codeblock language-tsx"><div class="rp-codeblock__title">network-requests/Phonebook.test.tsx</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="tsx" data-title="network-requests/Phonebook.test.tsx"><code><span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { render</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> screen</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> waitForElementToBeRemoved } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> '@testing-library/react-native'</span><span style="color:var(--shiki-foreground)">;</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> React </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> 'react'</span><span style="color:var(--shiki-foreground)">;</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> PhoneBook </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> '../PhoneBook'</span><span style="color:var(--shiki-foreground)">;</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> { User } </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> '../types'</span><span style="color:var(--shiki-foreground)">;</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> {http</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> HttpResponse} </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> "msw"</span><span style="color:var(--shiki-foreground)">;</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)">import</span><span style="color:var(--shiki-foreground)"> {setupServer} </span><span style="color:var(--shiki-token-keyword)">from</span><span style="color:var(--shiki-token-string-expression)"> "msw/node"</span><span style="color:var(--shiki-foreground)">;</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)">// Define request handlers and response resolvers for random user API.</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)">// By default, we always return the happy path response.</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)">const</span><span style="color:var(--shiki-token-constant)"> handlers</span><span style="color:var(--shiki-token-keyword)"> =</span><span style="color:var(--shiki-foreground)"> [</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-constant)"> http</span><span style="color:var(--shiki-token-function)">.get</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">'https://randomuser.me/api/*'</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> () </span><span style="color:var(--shiki-token-keyword)">=></span><span style="color:var(--shiki-foreground)"> {</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> return</span><span style="color:var(--shiki-token-constant)"> HttpResponse</span><span style="color:var(--shiki-token-function)">.json</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-constant)">DATA</span><span style="color:var(--shiki-foreground)">);</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> })</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)">];</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)">// Setup a request interception server with the given request handlers.</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)">const</span><span style="color:var(--shiki-token-constant)"> server</span><span style="color:var(--shiki-token-keyword)"> =</span><span style="color:var(--shiki-token-function)"> setupServer</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-keyword)">...</span><span style="color:var(--shiki-foreground)">handlers);</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)">// Enable API mocking via Mock Service Worker (MSW)</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)">beforeAll</span><span style="color:var(--shiki-foreground)">(() </span><span style="color:var(--shiki-token-keyword)">=></span><span style="color:var(--shiki-token-constant)"> server</span><span style="color:var(--shiki-token-function)">.listen</span><span style="color:var(--shiki-foreground)">());</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)">// Reset any runtime request handlers we may add during the tests</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)">afterEach</span><span style="color:var(--shiki-foreground)">(() </span><span style="color:var(--shiki-token-keyword)">=></span><span style="color:var(--shiki-token-constant)"> server</span><span style="color:var(--shiki-token-function)">.resetHandlers</span><span style="color:var(--shiki-foreground)">());</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)">// Disable API mocking after the tests are done</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)">afterAll</span><span style="color:var(--shiki-foreground)">(() </span><span style="color:var(--shiki-token-keyword)">=></span><span style="color:var(--shiki-token-constant)"> server</span><span style="color:var(--shiki-token-function)">.close</span><span style="color:var(--shiki-foreground)">());</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)">describe</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">'PhoneBook'</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> () </span><span style="color:var(--shiki-token-keyword)">=></span><span style="color:var(--shiki-foreground)"> {</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)"> it</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">'fetches all contacts and favorites successfully and renders lists in sections correctly'</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-token-keyword)"> async</span><span style="color:var(--shiki-foreground)"> () </span><span style="color:var(--shiki-token-keyword)">=></span><span style="color:var(--shiki-foreground)"> {</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> await</span><span style="color:var(--shiki-token-function)"> render</span><span style="color:var(--shiki-foreground)">(<</span><span style="color:var(--shiki-token-constant)">PhoneBook</span><span style="color:var(--shiki-foreground)"> />);</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> await</span><span style="color:var(--shiki-token-function)"> waitForElementToBeRemoved</span><span style="color:var(--shiki-foreground)">(() </span><span style="color:var(--shiki-token-keyword)">=></span><span style="color:var(--shiki-token-constant)"> screen</span><span style="color:var(--shiki-token-function)">.getByText</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">/users data not quite there yet/</span><span style="color:var(--shiki-token-keyword)">i</span><span style="color:var(--shiki-foreground)">));</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)"> expect</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-keyword)">await</span><span style="color:var(--shiki-token-constant)"> screen</span><span style="color:var(--shiki-token-function)">.findByText</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">'Name: Mrs Ida Kristensen'</span><span style="color:var(--shiki-foreground)">))</span><span style="color:var(--shiki-token-function)">.toBeOnTheScreen</span><span style="color:var(--shiki-foreground)">();</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)"> expect</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-keyword)">await</span><span style="color:var(--shiki-token-constant)"> screen</span><span style="color:var(--shiki-token-function)">.findByText</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">'Email: ida.kristensen@example.com'</span><span style="color:var(--shiki-foreground)">))</span><span style="color:var(--shiki-token-function)">.toBeOnTheScreen</span><span style="color:var(--shiki-foreground)">();</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)"> expect</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-keyword)">await</span><span style="color:var(--shiki-token-constant)"> screen</span><span style="color:var(--shiki-token-function)">.findAllByText</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">/name/</span><span style="color:var(--shiki-token-keyword)">i</span><span style="color:var(--shiki-foreground)">))</span><span style="color:var(--shiki-token-function)">.toHaveLength</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-constant)">3</span><span style="color:var(--shiki-foreground)">);</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)"> expect</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-keyword)">await</span><span style="color:var(--shiki-token-constant)"> screen</span><span style="color:var(--shiki-token-function)">.findByText</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">/my favorites/</span><span style="color:var(--shiki-token-keyword)">i</span><span style="color:var(--shiki-foreground)">))</span><span style="color:var(--shiki-token-function)">.toBeOnTheScreen</span><span style="color:var(--shiki-foreground)">();</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)"> expect</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-keyword)">await</span><span style="color:var(--shiki-token-constant)"> screen</span><span style="color:var(--shiki-token-function)">.findAllByLabelText</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">'favorite-contact-avatar'</span><span style="color:var(--shiki-foreground)">))</span><span style="color:var(--shiki-token-function)">.toHaveLength</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-constant)">3</span><span style="color:var(--shiki-foreground)">);</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> });</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)">});</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)">const</span><span style="color:var(--shiki-token-constant)"> DATA</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> { results</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-function)"> User</span><span style="color:var(--shiki-foreground)">[] } </span><span style="color:var(--shiki-token-keyword)">=</span><span style="color:var(--shiki-foreground)"> {</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> results</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> [</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> {</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> name</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> title</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> 'Mrs'</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> first</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> 'Ida'</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> last</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> 'Kristensen'</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> email</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> 'ida.kristensen@example.com'</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> id</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> name</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> 'CPR'</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> value</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> '250562-5730'</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> picture</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-foreground)"> {</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> large</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> 'https://randomuser.me/api/portraits/women/26.jpg'</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> medium</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> 'https://randomuser.me/api/portraits/med/women/26.jpg'</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> thumbnail</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> 'https://randomuser.me/api/portraits/thumb/women/26.jpg'</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> cell</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-string-expression)"> '123-4567-890'</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> }</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)"> // For brevity, we have omitted the rest of the users, you can still find them in</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)"> // examples/cookbook/app/network-requests/__tests__/test-utils.ts</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> ...</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> ]</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="Copy code"><svg xmlns="http://www.w3.org/2000/svg" width="272" height="272" viewBox="0 0 272 272" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" fill-rule="evenodd" d="M45.883 23.368h123.823v22.514H68.396v146.336H45.883zm45.026 45.027H225.99v180.107H90.91zm22.514 22.513v135.08h90.053V90.908z" clip-rule="evenodd"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="271" height="271" viewBox="0 0 271 271" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="M112.687 203.223H90.174v-22.514h22.512v-22.514h22.512v22.514h-22.511zm-22.514-22.514H67.66v-22.514h22.513zm-22.514-22.514H45.146v-22.512H67.66zm90.054 0h-22.514v-22.512h22.514zm22.514-22.512h-22.514v-22.514h22.514zm22.513-22.514h-22.513V90.655h22.513zm22.514-22.514H202.74V68.143h22.514z"></path></svg></button></div></div></div>
|
|
<div class="rp-callout rp-callout--info"><div class="rp-callout__title">Info</div><div class="rp-callout__content"><p>
|
|
More info regarding how to describe the network using request handlers, intercepting a request and handling its response can be found in the <a href="https://mswjs.io/docs/getting-started#step-2-describe" target="_blank" rel="noopener noreferrer" class="rp-link">MSW's documentation</a>.</p></div></div>
|
|
<h2 class="rp-toc-include" id="testing-error-handling"><a href="#testing-error-handling" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Testing error handling</h2>
|
|
<p>As we are dealing with network requests, and things can go wrong, we should also cover the case when
|
|
the API request fails. In this case, we would like to test how our application behaves when the API request fails.</p>
|
|
<div class="rp-callout rp-callout--info"><div class="rp-callout__title">Info</div><div class="rp-callout__content"><p>
|
|
The nature of the network can be highly dynamic, which makes it challenging to describe it completely in a fixed list of request handlers.
|
|
MSW provides us the means to override any particular network behavior using the designated <code>.use()</code> API.
|
|
More info can be found in <a href="https://mswjs.io/docs/best-practices/network-behavior-overrides" target="_blank" rel="noopener noreferrer" class="rp-link">MSW's Network behavior overrides documentation</a></p></div></div>
|
|
<div class="rp-codeblock language-tsx"><div class="rp-codeblock__title">network-requests/Phonebook.test.tsx</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="tsx" data-title="network-requests/Phonebook.test.tsx"><code><span class="line"><span style="color:var(--shiki-token-keyword)">...</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)">const</span><span style="color:var(--shiki-token-function)"> mockServerFailureForGetAllContacts</span><span style="color:var(--shiki-token-keyword)"> =</span><span style="color:var(--shiki-foreground)"> () </span><span style="color:var(--shiki-token-keyword)">=></span><span style="color:var(--shiki-foreground)"> {</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-constant)"> server</span><span style="color:var(--shiki-token-function)">.use</span><span style="color:var(--shiki-foreground)">(</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-constant)"> http</span><span style="color:var(--shiki-token-function)">.get</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">'https://randomuser.me/api/'</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> ({ request }) </span><span style="color:var(--shiki-token-keyword)">=></span><span style="color:var(--shiki-foreground)"> {</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)"> // Construct a URL instance out of the intercepted request.</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> const</span><span style="color:var(--shiki-token-constant)"> url</span><span style="color:var(--shiki-token-keyword)"> =</span><span style="color:var(--shiki-token-keyword)"> new</span><span style="color:var(--shiki-token-function)"> URL</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-constant)">request</span><span style="color:var(--shiki-foreground)">.url);</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)"> // Read the "results" URL query parameter using the "URLSearchParams" API.</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> const</span><span style="color:var(--shiki-token-constant)"> resultsLength</span><span style="color:var(--shiki-token-keyword)"> =</span><span style="color:var(--shiki-token-constant)"> url</span><span style="color:var(--shiki-token-function)">.</span><span style="color:var(--shiki-token-constant)">searchParams</span><span style="color:var(--shiki-token-function)">.get</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">'results'</span><span style="color:var(--shiki-foreground)">);</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)"> // Simulate a server error for the get all contacts request.</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)"> // We check if the "results" query parameter is set to "25"</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)"> // to know it's the correct request to mock, in our case get all contacts.</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> if</span><span style="color:var(--shiki-foreground)"> (resultsLength </span><span style="color:var(--shiki-token-keyword)">===</span><span style="color:var(--shiki-token-string-expression)"> '25'</span><span style="color:var(--shiki-foreground)">) {</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> return</span><span style="color:var(--shiki-token-keyword)"> new</span><span style="color:var(--shiki-token-function)"> HttpResponse</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-constant)">null</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> { status</span><span style="color:var(--shiki-token-keyword)">:</span><span style="color:var(--shiki-token-constant)"> 500</span><span style="color:var(--shiki-foreground)"> });</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> }</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)"> // Return the default response for all other requests that match URL and verb. (in our case get favorites)</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> return</span><span style="color:var(--shiki-token-constant)"> HttpResponse</span><span style="color:var(--shiki-token-function)">.json</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-constant)">DATA</span><span style="color:var(--shiki-foreground)">);</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> })</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> );</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)">};</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)">describe</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">'PhoneBook'</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-foreground)"> () </span><span style="color:var(--shiki-token-keyword)">=></span><span style="color:var(--shiki-foreground)"> {</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)">...</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)"> it</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">'fails to fetch all contacts and renders error message'</span><span style="color:var(--shiki-token-punctuation)">,</span><span style="color:var(--shiki-token-keyword)"> async</span><span style="color:var(--shiki-foreground)"> () </span><span style="color:var(--shiki-token-keyword)">=></span><span style="color:var(--shiki-foreground)"> {</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)"> mockServerFailureForGetAllContacts</span><span style="color:var(--shiki-foreground)">();</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> await</span><span style="color:var(--shiki-token-function)"> render</span><span style="color:var(--shiki-foreground)">(<</span><span style="color:var(--shiki-token-constant)">PhoneBook</span><span style="color:var(--shiki-foreground)"> />);</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> await</span><span style="color:var(--shiki-token-function)"> waitForElementToBeRemoved</span><span style="color:var(--shiki-foreground)">(() </span><span style="color:var(--shiki-token-keyword)">=></span><span style="color:var(--shiki-token-constant)"> screen</span><span style="color:var(--shiki-token-function)">.getByText</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">/users data not quite there yet/</span><span style="color:var(--shiki-token-keyword)">i</span><span style="color:var(--shiki-foreground)">));</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)"> expect</span><span style="color:var(--shiki-foreground)">(</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-keyword)"> await</span><span style="color:var(--shiki-token-constant)"> screen</span><span style="color:var(--shiki-token-function)">.findByText</span><span style="color:var(--shiki-foreground)">(</span><span style="color:var(--shiki-token-string-expression)">/an error occurred: error fetching contacts/</span><span style="color:var(--shiki-token-keyword)">i</span><span style="color:var(--shiki-foreground)">)</span><span style="color:var(--shiki-token-punctuation)">,</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> )</span><span style="color:var(--shiki-token-function)">.toBeOnTheScreen</span><span style="color:var(--shiki-foreground)">();</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)"> });</span></span>
|
|
<span class="line"><span style="color:var(--shiki-foreground)">});</span></span>
|
|
<span class="line"></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="Copy code"><svg xmlns="http://www.w3.org/2000/svg" width="272" height="272" viewBox="0 0 272 272" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" fill-rule="evenodd" d="M45.883 23.368h123.823v22.514H68.396v146.336H45.883zm45.026 45.027H225.99v180.107H90.91zm22.514 22.513v135.08h90.053V90.908z" clip-rule="evenodd"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="271" height="271" viewBox="0 0 271 271" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="M112.687 203.223H90.174v-22.514h22.512v-22.514h22.512v22.514h-22.511zm-22.514-22.514H67.66v-22.514h22.513zm-22.514-22.514H45.146v-22.512H67.66zm90.054 0h-22.514v-22.512h22.514zm22.514-22.512h-22.514v-22.514h22.514zm22.513-22.514h-22.513V90.655h22.513zm22.514-22.514H202.74V68.143h22.514z"></path></svg></button></div></div></div>
|
|
<h2 class="rp-toc-include" id="global-guarding-against-unwanted-api-requests"><a href="#global-guarding-against-unwanted-api-requests" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Global guarding against unwanted API requests</h2>
|
|
<p>As mistakes may happen, we might forget to mock a network request in one of our tests in the future.
|
|
To prevent us from happening, and alert when a certain network request is left unhandled, you may choose to
|
|
move MSW's server management from <code>PhoneBook.test.tsx</code> to Jest's setup file via <a href="https://jestjs.io/docs/configuration#setupfilesafterenv-array" target="_blank" rel="noopener noreferrer" class="rp-link"><code>setupFilesAfterEnv</code></a>.</p>
|
|
<div class="rp-codeblock language-tsx"><div class="rp-codeblock__title">examples/cookbook/jest-setup.ts</div><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="tsx" data-title="examples/cookbook/jest-setup.ts"><code><span class="line"><span style="color:var(--shiki-token-comment)">// Enable API mocking via Mock Service Worker (MSW)</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)">beforeAll</span><span style="color:var(--shiki-foreground)">(() </span><span style="color:var(--shiki-token-keyword)">=></span><span style="color:var(--shiki-token-constant)"> server</span><span style="color:var(--shiki-token-function)">.listen</span><span style="color:var(--shiki-foreground)">());</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)">// Reset any runtime request handlers we may add during the tests</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)">afterEach</span><span style="color:var(--shiki-foreground)">(() </span><span style="color:var(--shiki-token-keyword)">=></span><span style="color:var(--shiki-token-constant)"> server</span><span style="color:var(--shiki-token-function)">.resetHandlers</span><span style="color:var(--shiki-foreground)">());</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)">// Disable API mocking after the tests are done</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)">afterAll</span><span style="color:var(--shiki-foreground)">(() </span><span style="color:var(--shiki-token-keyword)">=></span><span style="color:var(--shiki-token-constant)"> server</span><span style="color:var(--shiki-token-function)">.close</span><span style="color:var(--shiki-foreground)">());</span></span>
|
|
<span class="line"></span>
|
|
<span class="line"><span style="color:var(--shiki-token-comment)">// ... rest of your setup file</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="Copy code"><svg xmlns="http://www.w3.org/2000/svg" width="272" height="272" viewBox="0 0 272 272" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" fill-rule="evenodd" d="M45.883 23.368h123.823v22.514H68.396v146.336H45.883zm45.026 45.027H225.99v180.107H90.91zm22.514 22.513v135.08h90.053V90.908z" clip-rule="evenodd"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="271" height="271" viewBox="0 0 271 271" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="M112.687 203.223H90.174v-22.514h22.512v-22.514h22.512v22.514h-22.511zm-22.514-22.514H67.66v-22.514h22.513zm-22.514-22.514H45.146v-22.512H67.66zm90.054 0h-22.514v-22.512h22.514zm22.514-22.512h-22.514v-22.514h22.514zm22.513-22.514h-22.513V90.655h22.513zm22.514-22.514H202.74V68.143h22.514z"></path></svg></button></div></div></div>
|
|
<p>This setup will ensure you have the MSW server running before any test suite starts and stops it after all tests are done.
|
|
Which will result in a warning in the console if you forget to mock an API request in your test suite.</p>
|
|
<div class="rp-codeblock language-bash"><div class="rp-codeblock__content"><div class="rp-codeblock__content__scroll-container rp-scrollbar rp-scrollbar--always"><pre class="shiki css-variables" style="background-color:var(--shiki-background);color:var(--shiki-foreground)" tabindex="0" data-lang="bash"><code><span class="line"><span style="color:var(--shiki-foreground)">[MSW] Warning: intercepted a request without a matching request handler:</span></span>
|
|
<span class="line"><span style="color:var(--shiki-token-function)"> •</span><span style="color:var(--shiki-token-string)"> GET</span><span style="color:var(--shiki-token-string)"> https://randomuser.me/api/?results=25?results=</span><span style="color:var(--shiki-token-constant)">25</span></span></code></pre></div><div class="rp-code-button-group"><button class="rp-code-button-group__button rp-code-wrap-button" title="Toggle code wrap"><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrapped"><path fill="currentColor" d="M21 5H3v2h18zM3 19h7v-2H3zm0-6h15c1 0 2 .43 2 2s-1 2-2 2h-2v-2l-4 3 4 3v-2h2c2.95 0 4-1.27 4-4 0-2.72-1-4-4-4H3z"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" class="rp-code-button-group__icon rp-code-button-group__icon--wrap"><path fill="currentColor" d="M16 7H3V5h13zM3 19h13v-2H3zm19-7-4-3v2H3v2h15v2z"></path></svg></button><button class="rp-code-button-group__button rp-code-copy-button" title="Copy code"><svg xmlns="http://www.w3.org/2000/svg" width="272" height="272" viewBox="0 0 272 272" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--copy"><path fill="currentColor" fill-rule="evenodd" d="M45.883 23.368h123.823v22.514H68.396v146.336H45.883zm45.026 45.027H225.99v180.107H90.91zm22.514 22.513v135.08h90.053V90.908z" clip-rule="evenodd"></path></svg><svg xmlns="http://www.w3.org/2000/svg" width="271" height="271" viewBox="0 0 271 271" class="rp-code-button-group__icon rp-code-copy-button__icon rp-code-copy-button__icon--success"><path fill="currentColor" d="M112.687 203.223H90.174v-22.514h22.512v-22.514h22.512v22.514h-22.511zm-22.514-22.514H67.66v-22.514h22.513zm-22.514-22.514H45.146v-22.512H67.66zm90.054 0h-22.514v-22.512h22.514zm22.514-22.512h-22.514v-22.514h22.514zm22.513-22.514h-22.513V90.655h22.513zm22.514-22.514H202.74V68.143h22.514z"></path></svg></button></div></div></div>
|
|
<h2 class="rp-toc-include" id="conclusion"><a href="#conclusion" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Conclusion</h2>
|
|
<p>Testing a component that makes network requests in combination with MSW takes some initial preparation to configure and describe the overridden networks.
|
|
We can achieve that by using MSW's request handlers and intercepting APIs.</p>
|
|
<p>Once up and running we gain full grip over the network requests, their responses, statuses.
|
|
Doing so is crucial to be able to test how our application behaves in different
|
|
scenarios, such as when the request is successful or when it fails.</p>
|
|
<p>When global configuration is in place, MSW's will also warn us when an unhandled network requests has occurred throughout a test suite.</p>
|
|
<h2 class="rp-toc-include" id="further-reading-and-alternatives"><a href="#further-reading-and-alternatives" class="rp-header-anchor rp-link" aria-hidden="true">#</a>Further Reading and Alternatives</h2>
|
|
<p>Explore more advanced scenarios for mocking network requests with MSW:</p>
|
|
<ul>
|
|
<li>MSW's Basics - <a href="https://mswjs.io/docs/basics/intercepting-requests" target="_blank" rel="noopener noreferrer" class="rp-link">Intercepting requests</a> and/or <a href="https://mswjs.io/docs/basics/mocking-responses" target="_blank" rel="noopener noreferrer" class="rp-link">Mocking responses</a></li>
|
|
<li>MSW's Network behavior - how to describe <a href="https://mswjs.io/docs/network-behavior/rest" target="_blank" rel="noopener noreferrer" class="rp-link">REST</a> and/or <a href="https://mswjs.io/docs/network-behavior/graphql" target="_blank" rel="noopener noreferrer" class="rp-link">GraphQL</a> APIs</li>
|
|
</ul><!--/$--></div><div class="container-uhcWmO"><img class="logo-IwzwG8" src="/react-native-testing-library/static/image/abstract-atom.4eca0300ff.avif" alt="Abstract Logo" aria-hidden="true"/><div class="content-uJxcIj"><div class="headlineContainer-NHNT4y"><h1 class="headline-iCUUUl">Need React or React Native
|
|
expertise you can count on?</h1></div><div class="buttonContainer-wOj8Y6"><div class="dark"><a href="https://www.callstack.com/contact" class="button-DogSnd brand-rT2ahT ">Let's talk<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none" viewBox="0 0 16 16" class="button-icon-Okk0hT" aria-hidden="true" focusable="false"><path fill="currentColor" d="M9.333 13.333h1.334V12H9.333zm-6.666-2.666h8V12H12v-1.333h1.333V9.333H12V8h-1.333v1.333H4V2.667H2.667zM9.333 8h1.334V6.667H9.333z"></path></svg></a></div></div></div></div><footer class="rp-doc-footer"><div class="rp-doc-footer__edit"></div><div class="rp-doc-footer__divider"></div><div class="container-aZLxg0"><a href="/react-native-testing-library/cookbook/basics/custom-render" class="pagerLink-_WIlZJ rp-link"><span class="iconBox-AUO0Le"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 24 24" class="icon-WRLCnG"><path d="M4 20h2V4H4zm8-5v2h2v-2zm-2-4H8v2h2v2h2v-2h8v-2h-8V9h-2zm2-2h2V7h-2z"></path></svg></span><span class="textWrap-lmdyLc"><span class="desc-sp3vRh">Previous page</span><span class="title-hrit_i">Custom Render</span></span></a><a href="/react-native-testing-library/cookbook/state-management/jotai" class="pagerLink-_WIlZJ next-axkYXz rp-link"><span class="textWrap-lmdyLc"><span class="desc-sp3vRh">Next page</span><span class="title-hrit_i">Jotai</span></span><span class="iconBox-AUO0Le"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 24 24" class="icon-WRLCnG"><path d="M20 20h-2V4h2zm-8-5v2h-2v-2zm2-4h2v2h-2v2h-2v-2H4v-2h8V9h2zm-2-2h-2V7h2z"></path></svg></span></a></div></footer></main></div><aside class="rp-doc-layout__outline rp-scrollbar"><div class="rp-outline"><div class="rp-outline__title">Contents<svg width="14" height="14" class="rp-progress-circle"><circle cx="7" cy="7" r="6" stroke-linecap="round" fill="none" stroke="var(--rp-c-divider-light)" stroke-width="2"></circle><circle cx="7" cy="7" r="6" stroke-linecap="round" fill="none" stroke="var(--rp-c-brand)" stroke-width="2" stroke-dasharray="37.69911184307752" stroke-dashoffset="37.69911184307752" transform="rotate(-90 7 7)" style="transition:stroke-dashoffset 0.3s"></circle></svg></div><nav class="rp-outline__toc rp-scrollbar"><a href="#introduction" class="rp-toc-item rp-link" title="Introduction" style="padding-left:0" data-depth="0"><span class="rp-toc-item__text rp-doc">Introduction</span></a><a href="#phonebook-example" class="rp-toc-item rp-link" title="Phonebook Example" style="padding-left:0" data-depth="0"><span class="rp-toc-item__text rp-doc">Phonebook Example</span></a><a href="#start-testing-with-a-simple-test" class="rp-toc-item rp-link" title="Start testing with a simple test" style="padding-left:0" data-depth="0"><span class="rp-toc-item__text rp-doc">Start testing with a simple test</span></a><a href="#testing-error-handling" class="rp-toc-item rp-link" title="Testing error handling" style="padding-left:0" data-depth="0"><span class="rp-toc-item__text rp-doc">Testing error handling</span></a><a href="#global-guarding-against-unwanted-api-requests" class="rp-toc-item rp-link" title="Global guarding against unwanted API requests" style="padding-left:0" data-depth="0"><span class="rp-toc-item__text rp-doc">Global guarding against unwanted API requests</span></a><a href="#conclusion" class="rp-toc-item rp-link" title="Conclusion" style="padding-left:0" data-depth="0"><span class="rp-toc-item__text rp-doc">Conclusion</span></a><a href="#further-reading-and-alternatives" class="rp-toc-item rp-link" title="Further Reading and Alternatives" style="padding-left:0" data-depth="0"><span class="rp-toc-item__text rp-doc">Further Reading and Alternatives</span></a></nav><div class="rp-outline__divider"></div><div class="rp-outline__bottom"></div></div><div class="rp-outline__divider"></div><div class="container-LzbylO"><div><div class="headline-y75_LS">Need help with React or React Native projects?</div><div class="description-muYVs3">We support teams building scalable apps with React and React Native.</div></div><a href="https://www.callstack.com/contact" class="button-DogSnd brand-rT2ahT ">Let's talk<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none" viewBox="0 0 16 16" class="button-icon-Okk0hT" aria-hidden="true" focusable="false"><path fill="currentColor" d="M9.333 13.333h1.334V12H9.333zm-6.666-2.666h8V12H12v-1.333h1.333V9.333H12V8h-1.333v1.333H4V2.667H2.667zM9.333 8h1.334V6.667H9.333z"></path></svg></a></div></aside></div></div>
|
|
<div id="__rspress_modal_container"></div>
|
|
</body>
|
|
</html>
|