{"componentChunkName":"component---node-modules-rocketseat-gatsby-theme-docs-core-src-templates-docs-query-js","path":"/react-js/apiCalls","result":{"data":{"mdx":{"id":"4ba794f9-7422-56ec-bd77-c2dcc48521de","excerpt":"When we are creating websites, there is a cool term you have come across - 'state'. Think of it like a photo capturing a specific moment of your website. It's a…","fields":{"slug":"/react-js/apiCalls/"},"frontmatter":{"title":"React: API Interaction. useEffect","description":"API Interaction | React | RefugeesCode","image":null,"disableTableOfContents":null},"body":"function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\n/* @jsxRuntime classic */\n\n/* @jsx mdx */\nvar _frontmatter = {\n  \"title\": \"React: API Interaction. useEffect\",\n  \"description\": \"API Interaction | React | RefugeesCode\"\n};\nvar layoutProps = {\n  _frontmatter: _frontmatter\n};\nvar MDXLayout = \"wrapper\";\nreturn function MDXContent(_ref) {\n  var components = _ref.components,\n      props = _objectWithoutProperties(_ref, [\"components\"]);\n\n  return mdx(MDXLayout, _extends({}, layoutProps, props, {\n    components: components,\n    mdxType: \"MDXLayout\"\n  }), mdx(\"p\", null, \"When we are creating websites, there is a cool term you have come across - 'state'. Think of it like a photo capturing a specific moment of your website. It's a way to keep track of what's happening on your screen at any given time.\"), mdx(\"p\", null, \"For example, imagine you're filling out a form on a website. The words you type into the boxes? That's part of the state. Or maybe there are parts of the website that can be hidden or shown with a click of a button. Whether these parts are visible or not, that's also part of the state.\"), mdx(\"p\", null, \"And it's not just about what you can see. The state also includes the data that the website is handling. Let's say there's a table on the website showing the latest scores for your favorite sports team. The scores in that table are part of the state too.\"), mdx(\"p\", null, \"So, in a nutshell, the state keeps track of what's going on with the user interface and the data it's dealing with. It's a super important concept in web development and makes websites interactive and dynamic. We have already talked about it in the \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://refugeescode-materials.netlify.app/react-js/states\"\n  }, \"useState\"), \" class.\"), mdx(\"p\", null, \"For those operations which state depends on external resources, for example, data coming from a ReST API, we will use React's hook \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"useEffect\"), \".\"), mdx(\"h2\", {\n    \"id\": \"goals\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", {\n    parentName: \"h2\",\n    \"href\": \"#goals\",\n    \"aria-label\": \"goals permalink\",\n    \"className\": \"anchor before\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  }))), \"Goals\"), mdx(\"p\", null, \"In this class, we will explore the power of the useEffect hook and how it can help you effectively manage side effects in your React applications, with a focus on fetching data from APIs. By the end of this session, you will:\"), mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Understand the concept of side effects in the context of React development and why they are important to manage, particularly when it comes to data fetching.\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Learn how to use the useEffect hook to handle data fetching from APIs, including using libraries like Axios or the built-in fetch API.\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Explore the use of Async/Await in React components to handle asynchronous data fetching.\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Discover how to manage the fetched data in the component's state using the useState hook.\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Learn best practices for cleaning up effects and optimizing performance when working with useEffect.\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Gain the knowledge and confidence to leverage the useEffect hook to build robust, data-driven React components that seamlessly integrate with APIs.\")), mdx(\"p\", null, \"This understanding of the useEffect hook and API integration will be crucial as you progress through the rest of the React course, where you'll learn about more advanced state management techniques and build complex, interactive user interfaces.\"), mdx(\"h2\", {\n    \"id\": \"useeffect\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", {\n    parentName: \"h2\",\n    \"href\": \"#useeffect\",\n    \"aria-label\": \"useeffect permalink\",\n    \"className\": \"anchor before\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  }))), \"useEffect\"), mdx(\"p\", null, \"The useEffect hook is a fundamental part of React's Hooks system, allowing you to perform side effects in functional components. Side effects are any operations that can affect something outside the scope of the current function, such as data fetching, manual DOM manipulations, and subscriptions.\\nLet's start learning how useEffect works by executing this example:\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-javascript\"\n  }, \"import React, { useState, useEffect } from \\\"react\\\";\\n\\nfunction MyComponent() {\\n  // Use the useState hook to manage the count state\\n  const [count, setCount] = useState(0);\\n\\n  // The first useEffect call runs once, when the component mounts\\n  // This is indicated by the empty dependency array []\\n  useEffect(() => {\\n    // Log a message to the console when the component mounts\\n    console.log(\\\"Component mounted!\\\");\\n  }, []);\\n\\n  // The second useEffect call runs whenever the count state changes\\n  // This is indicated by the dependency array [count]\\n  useEffect(() => {\\n    // Log the current value of the count to the console\\n    console.log(`The count is now: ${count}`);\\n  }, [count]);\\n\\n  return (\\n    <div>\\n      <h1>My Component</h1>\\n      <p>The count is: {count}</p>\\n      <button onClick={() => setCount(count + 1)}>Increment</button>\\n    </div>\\n  );\\n}\\n\\nexport default MyComponent;\\n\")), mdx(\"p\", null, \"On this component the first useEffect call runs once, when the component is first mounted. This is indicated by the empty dependency array []. Inside this effect, we log a message to the console.\\nThe second useEffect call runs whenever the count state changes. This is indicated by the dependency array \", \"[count]\", \". Inside this effect, we log the current value of the count to the console.\"), mdx(\"h2\", {\n    \"id\": \"fetching-data-from-apis-in-react\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", {\n    parentName: \"h2\",\n    \"href\": \"#fetching-data-from-apis-in-react\",\n    \"aria-label\": \"fetching data from apis in react permalink\",\n    \"className\": \"anchor before\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  }))), \"Fetching data from APIs in React\"), mdx(\"p\", null, \"That's a basic example to understand how useEffect works. Now let put it into practice with a real-world task: fetching data from an API.\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-javascript\"\n  }, \"import React, { useState, useEffect } from 'react';\\n\\nfunction MyComponent() {\\n  const [users, setUsers] = useState([]);\\n\\n  // Fetch users data when the component mounts\\n  useEffect(() => {\\n    const fetchUsers = () => {\\n      try {\\n        fetch('https://jsonplaceholder.typicode.com/users').then(response => response.json().then(data => setUsers(data) )\\n\\n      } catch (error) {\\n        console.error('Error fetching users:', error);\\n      }\\n    };\\n\\n    fetchUsers();\\n  }, []);\\n\\n  return (\\n    <div>\\n      <h1>Users</h1>\\n      <ul>\\n        {users.map((user) => (\\n          <li key={user.id}>{user.name}</li>\\n        ))}\\n      </ul>\\n    </div>\\n  );\\n}\\n\\nexport default MyComponent;\\n\")), mdx(\"p\", null, \"We are fetching data from \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"jsonplaceholder.typicode.com/users\"\n  }, \"jsonplaceholder.typicode.com/users\"), \" and then rendering a list of users after when receive the data asynchronously.\\nthe fetchUsers function now uses the .then() syntax to handle the asynchronous nature of the fetch call.\\nThe first .then() call handles the response from the fetch call and converts it to JSON using response.json().\\nThe second .then() call takes the JSON data and updates the users state using setUsers.\\nThe try/catch block remains the same, catching any errors that might occur during the data fetching process.\\nWe can also using an external library called axios to fetch the data\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-javascript\"\n  }, \"import React, { useState, useEffect } from \\\"react\\\";\\nimport axios from \\\"axios\\\";\\n\\nfunction MyComponent() {\\n  const [users, setUsers] = useState([]);\\n\\n  // Fetch users data when the component mounts\\n  useEffect(() => {\\n    const fetchUsers = async () => {\\n      try {\\n        const response = await axios.get(\\n          \\\"https://jsonplaceholder.typicode.com/users\\\"\\n        );\\n        setUsers(response.data);\\n      } catch (error) {\\n        console.error(\\\"Error fetching users:\\\", error);\\n      }\\n    };\\n\\n    fetchUsers();\\n  }, []);\\n\\n  return (\\n    <div>\\n      <h1>Users</h1>\\n      <ul>\\n        {users.map((user) => (\\n          <li key={user.id}>{user.name}</li>\\n        ))}\\n      </ul>\\n    </div>\\n  );\\n}\\n\\nexport default MyComponent;\\n\")), mdx(\"p\", null, \"The result is the same. Using an external library to do the same as a native Web API such as fetch is a decision meant for you and your team.\"), mdx(\"h2\", {\n    \"id\": \"asyncawait-in-react\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", {\n    parentName: \"h2\",\n    \"href\": \"#asyncawait-in-react\",\n    \"aria-label\": \"asyncawait in react permalink\",\n    \"className\": \"anchor before\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  }))), \"Async/Await in React\"), mdx(\"p\", null, \"Another way to handle asynchronous code is by using async/await. They are syntactic sugar created on top of JavaScript Promises, so instead of using then and catch you can the result of a promise on a variable by invoking it with the word \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"await\"), \"right in front of it.\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-javascript\"\n  }, \"import React, { useState, useEffect } from \\\"react\\\";\\n\\nfunction MyComponent() {\\n  const [users, setUsers] = useState([]);\\n\\n  // Fetch users data when the component mounts\\n  useEffect(() => {\\n    /*typically you would do:\\n     fetch(\\\"https://jsonplaceholder.typicode.com/users\\\")\\n      .then(response => response.json())\\n      .then(data => setUsers(data))*/ \\n    const fetchUsers = async () => {\\n        const response = await fetch(\\\"https://jsonplaceholder.typicode.com/users\\\")\\n        const data = await response.json();\\n        setUsers(data);\\n    };\\n\\n    fetchUsers();\\n  }, []);\\n\\n  return (\\n    <div>\\n      <h1>Users</h1>\\n      <ul>\\n        {users.map((user) => (\\n          <li key={user.id}>{user.name}</li>\\n        ))}\\n      </ul>\\n    </div>\\n  );\\n}\\n\\nexport default MyComponent;\\n\")), mdx(\"p\", null, \"The same example but using try/catch to handle errors in API fetching.\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-javascript\"\n  }, \"import React, { useState, useEffect } from \\\"react\\\";\\n\\nfunction MyComponent() {\\n  const [users, setUsers] = useState([]);\\n\\n  // Fetch users data when the component mounts\\n  useEffect(() => {\\n    const fetchUsers = async () => {\\n      try {\\n        const response = await fetch(\\n          \\\"https://jsonplaceholder.typicode.com/users\\\"\\n        );\\n        const data = await response.json();\\n        setUsers(data);\\n      } catch (error) {\\n        console.error(\\\"Error fetching users:\\\", error);\\n      }\\n    };\\n\\n    fetchUsers();\\n  }, []);\\n\\n  return (\\n    <div>\\n      <h1>Users</h1>\\n      <ul>\\n        {users.map((user) => (\\n          <li key={user.id}>{user.name}</li>\\n        ))}\\n      </ul>\\n    </div>\\n  );\\n}\\n\\nexport default MyComponent;\\n\")), mdx(\"h2\", {\n    \"id\": \"cleaning-the-effect\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", {\n    parentName: \"h2\",\n    \"href\": \"#cleaning-the-effect\",\n    \"aria-label\": \"cleaning the effect permalink\",\n    \"className\": \"anchor before\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  }))), \"Cleaning the effect\"), mdx(\"p\", null, \"Everytime we add a new component to the DOM, we say the component is 'mounted'. On the other hand, it is 'unmounted' when we remove it from the DOM. For example, a notification is mounted when it appears on the screen and it is unmounted when it dissapears.\", mdx(\"br\", {\n    parentName: \"p\"\n  }), \"\\n\", \"When we add a function to an event linked to a component, that function could generate problems if it's not properly cleaned. useEffect provides a way to clean the function: by clearing the function/removing the event listener on the return statement of the useEffect.\", mdx(\"br\", {\n    parentName: \"p\"\n  }), \"\\n\", \"Here's an example of two components, one cleaned and the other uncleaned to see the difference between the two.\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-javascript\"\n  }, \"import React, { useEffect, useState } from 'react';\\n\\nconst UncleanedComponent = () => {\\n  const [count, setCount] = useState(0);\\n\\n  useEffect(() => {\\n    const interval = setInterval(() => {\\n      console.log('Interval running in uncleaned component');\\n      setCount((count) => count + 1);\\n    }, 1000);\\n\\n    // No cleanup function returned\\n  }, []);\\n\\n  return (\\n    <div>\\n      <h2>Uncleaned Component</h2>\\n      <p>Count: {count}</p>\\n    </div>\\n  );\\n};\\n\\nconst CleanedComponent = () => {\\n  const [count, setCount] = useState(0);\\n\\n  useEffect(() => {\\n    const interval = setInterval(() => {\\n      console.log('Interval running in cleaned component');\\n      setCount((count) => count + 1);\\n    }, 1000);\\n\\n    // Clean up the interval when the component is unmounted\\n    return () => clearInterval(interval);\\n  }, []);\\n\\n  return (\\n    <div>\\n      <h2>Cleaned Component</h2>\\n      <p>Count: {count}</p>\\n    </div>\\n  );\\n};\\n\\nconst App = () => {\\n  const [showComponents, setShowComponents] = useState(true);\\n\\n  return (\\n    <div>\\n      <button onClick={() => setShowComponents(!showComponents)}>\\n        {showComponents ? 'Unmount Components' : 'Mount Components'}\\n      </button>\\n      {showComponents && (\\n        <>\\n          <UncleanedComponent />\\n          <CleanedComponent />\\n        </>\\n      )}\\n    </div>\\n  );\\n};\\n\\nexport default App;\\n\")), mdx(\"p\", null, \"On this \", mdx(\"a\", {\n    parentName: \"p\",\n    \"href\": \"https://stackblitz.com/edit/vitejs-vite-k9ndcg?file=src%2FApp.jsx\"\n  }, \"link\"), \" you can access the example and try it by yourself.    \"), mdx(\"p\", null, \"Another example:\"), mdx(\"pre\", null, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-javascript\"\n  }, \"import React, { useEffect, useState } from \\\"react\\\";\\n\\nexport default function Resize() {\\n  const [windowWidth, setWindowWidth] = useState(window.innerWidth);\\n\\n  useEffect(() => {\\n    // Set up the event listener\\n    const handleResize = () => {\\n      // Handle resize logic\\n      setWindowWidth(window.innerWidth);\\n    };\\n    window.addEventListener(\\\"resize\\\", handleResize);\\n\\n    // Clean up the event listener when the component unmounts\\n    return () => {\\n      window.removeEventListener(\\\"resize\\\", handleResize);\\n    };\\n  },[]); // Empty dependency array to run only once\\n\\n  return (\\n    <div>\\n      <h1>Window Width: {windowWidth}</h1>\\n    </div>\\n  );\\n}\\n\\n\")), mdx(\"h2\", {\n    \"id\": \"exercise\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", {\n    parentName: \"h2\",\n    \"href\": \"#exercise\",\n    \"aria-label\": \"exercise permalink\",\n    \"className\": \"anchor before\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  }))), \"Exercise\"), mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Based on the \", mdx(\"a\", {\n    parentName: \"li\",\n    \"href\": \"https://stackblitz.com/edit/vitejs-vite-mzvefv?file=src%2FApp.jsx\"\n  }, \"React Router practice\"), \", implement the productsList fetching data from \", mdx(\"a\", {\n    parentName: \"li\",\n    \"href\": \"https://fakestoreapi.com/products\"\n  }, \"https://fakestoreapi.com/products\"), mdx(\"br\", {\n    parentName: \"li\"\n  }), \"You can use this \", mdx(\"a\", {\n    parentName: \"li\",\n    \"href\": \"https://github.com/cmarchena/mfr-useEffect\"\n  }, \"repo\"), \" as starting point.\\nHave fun and keep coding!\")), mdx(\"h2\", {\n    \"id\": \"further-reading\",\n    \"style\": {\n      \"position\": \"relative\"\n    }\n  }, mdx(\"a\", {\n    parentName: \"h2\",\n    \"href\": \"#further-reading\",\n    \"aria-label\": \"further reading permalink\",\n    \"className\": \"anchor before\"\n  }, mdx(\"svg\", {\n    parentName: \"a\",\n    \"aria-hidden\": \"true\",\n    \"focusable\": \"false\",\n    \"height\": \"16\",\n    \"version\": \"1.1\",\n    \"viewBox\": \"0 0 16 16\",\n    \"width\": \"16\"\n  }, mdx(\"path\", {\n    parentName: \"svg\",\n    \"fillRule\": \"evenodd\",\n    \"d\": \"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"\n  }))), \"Further Reading\"), mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, mdx(\"a\", {\n    parentName: \"li\",\n    \"href\": \"https://react.dev/reference/react/useEffect\"\n  }, \"React Documentation\"))));\n}\n;\nMDXContent.isMDXComponent = true;","headings":[{"depth":2,"value":"Goals"},{"depth":2,"value":"useEffect"},{"depth":2,"value":"Fetching data from APIs in React"},{"depth":2,"value":"Async/Await in React"},{"depth":2,"value":"Cleaning the effect"},{"depth":2,"value":"Exercise"},{"depth":2,"value":"Further Reading"}]}},"pageContext":{"slug":"/react-js/apiCalls/","prev":{"label":"React Router","link":"/react-js/router"},"next":{"label":"Styling in React Sass","link":"/react-js/sass"},"repositoryEditUrl":"https://github.com/rocketseat/gatsby-themes/tree/main/examples/gatsby-theme-docs/src/docs/react-js/apiCalls.mdx","repositoryProvider":"GitHub"}},"staticQueryHashes":["1954253342","2328931024","2501019404","973074209"]}