{"componentChunkName":"component---src-gatsby-theme-try-ghost-templates-post-js","path":"/react-query-tutorial-for-beginners/","result":{"data":{"customPost":{"id":"Ghost__Post__62dd14674e918d05f353777d","title":"React (TanStack) Query Tutorial for Beginners","slug":"react-query-tutorial-for-beginners","featured":true,"feature_image":"https://backend.shahednasser.com/content/images/2022/07/React--TanStack--Query-Tutorial-for-Beginners.jpg","excerpt":"In this tutorial, you'll build a simple Node.js server and then learn how to interact with it on a React website using React Query.","custom_excerpt":"In this tutorial, you'll build a simple Node.js server and then learn how to interact with it on a React website using React Query.","visibility":"public","created_at_pretty":"24 Jul 2022","published_at_pretty":"24 Jul 2022","updated_at_pretty":"24 Jul 2022","created_at":"2022-07-24T09:44:07.000+00:00","published_at":"2022-07-24T15:50:35.000+00:00","updated_at":"2022-07-24T15:50:35.000+00:00","meta_title":null,"meta_description":null,"og_description":null,"og_image":null,"og_title":null,"twitter_description":null,"twitter_image":null,"twitter_title":null,"authors":[{"slug":"shahed","url":"https://backend.shahednasser.com/author/shahed/","name":"Shahed Nasser","bio":null,"cover_image":null,"profile_image":"https://backend.shahednasser.com/content/images/2022/03/IMG_0591.jpg","location":null,"website":null,"twitter":null,"facebook":null,"meta_title":null,"meta_description":null,"coverImageSharp":null,"profileImageSharp":null}],"primary_author":{"slug":"shahed","url":"https://backend.shahednasser.com/author/shahed/","name":"Shahed Nasser","bio":null,"cover_image":null,"profile_image":"https://backend.shahednasser.com/content/images/2022/03/IMG_0591.jpg","location":null,"website":null,"twitter":null,"facebook":null,"meta_title":null,"meta_description":null,"coverImageSharp":null,"profileImageSharp":{"base":"IMG_0591.jpg","publicURL":"/static/ceb49c3c631485453e71e00d7f84b069/IMG_0591.jpg","imageMeta":{"width":1182,"height":1179},"childImageSharp":{"fluid":{"base64":"data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAUABQDASIAAhEBAxEB/8QAGAABAQEBAQAAAAAAAAAAAAAAAAMEAQL/xAAWAQEBAQAAAAAAAAAAAAAAAAADBAL/2gAMAwEAAhADEAAAAdXiFM6i0CohUWXoKn//xAAcEAACAgIDAAAAAAAAAAAAAAACAwESBBEhM0H/2gAIAQEAAQUCWySE3WEr7SzbXjAj4iKty+sOQ//EABYRAQEBAAAAAAAAAAAAAAAAAAERIP/aAAgBAwEBPwEhj//EABQRAQAAAAAAAAAAAAAAAAAAACD/2gAIAQIBAT8BH//EAB4QAAIBBAMBAAAAAAAAAAAAAAABIRESMUECECJx/9oACAEBAAY/ApVGWvOjzgtUwLlTZA0sdL4f/8QAHBAAAwACAwEAAAAAAAAAAAAAAAERITFBkbHB/9oACAEBAAE/IahkCy+N2GwZpjQiJHJCspUFY0QrSi+HqiW2rgf/2gAMAwEAAgADAAAAEPw3/wD/xAAYEQEBAAMAAAAAAAAAAAAAAAAAARExQf/aAAgBAwEBPxCtjDqP/8QAFxEBAQEBAAAAAAAAAAAAAAAAAQAxEf/aAAgBAgEBPxBFus6Tt//EAB8QAQEAAgIBBQAAAAAAAAAAAAERACExQWFRcYGR0f/aAAgBAQABPxAuaBPPzkO1wyX7F4wkwXanfZrFQgeqE9JgS14vVOvrERIJomVBKwt2jebAeP0yVa8h1n//2Q==","aspectRatio":1,"src":"/static/ceb49c3c631485453e71e00d7f84b069/31709/IMG_0591.jpg","srcSet":"/static/ceb49c3c631485453e71e00d7f84b069/f340b/IMG_0591.jpg 28w,\n/static/ceb49c3c631485453e71e00d7f84b069/22d64/IMG_0591.jpg 55w,\n/static/ceb49c3c631485453e71e00d7f84b069/31709/IMG_0591.jpg 110w,\n/static/ceb49c3c631485453e71e00d7f84b069/aa249/IMG_0591.jpg 165w,\n/static/ceb49c3c631485453e71e00d7f84b069/0dc33/IMG_0591.jpg 220w,\n/static/ceb49c3c631485453e71e00d7f84b069/d8257/IMG_0591.jpg 1182w","srcWebp":"/static/ceb49c3c631485453e71e00d7f84b069/8678c/IMG_0591.webp","srcSetWebp":"/static/ceb49c3c631485453e71e00d7f84b069/59cda/IMG_0591.webp 28w,\n/static/ceb49c3c631485453e71e00d7f84b069/7da75/IMG_0591.webp 55w,\n/static/ceb49c3c631485453e71e00d7f84b069/8678c/IMG_0591.webp 110w,\n/static/ceb49c3c631485453e71e00d7f84b069/f282e/IMG_0591.webp 165w,\n/static/ceb49c3c631485453e71e00d7f84b069/a7b21/IMG_0591.webp 220w,\n/static/ceb49c3c631485453e71e00d7f84b069/63099/IMG_0591.webp 1182w","sizes":"(max-width: 110px) 100vw, 110px"}}}},"primary_tag":{"slug":"react","url":"https://backend.shahednasser.com/tag/react/","name":"React","visibility":"public","feature_image":"https://images.unsplash.com/photo-1581276879432-15e50529f34b?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=MnwxMTc3M3wwfDF8c2VhcmNofDN8fHJlYWN0fGVufDB8fHx8MTYyMjYzMzI0MA&ixlib=rb-1.2.1&q=80&w=2000","description":"Learn more about React through tutorials, articles, and tips.","meta_title":null,"meta_description":null,"featureImageSharp":{"base":"photo-1581276879432-15e50529f34b.jpg","publicURL":"/static/7140ea32e1157ba61402d5d67ab846d4/photo-1581276879432-15e50529f34b.jpg","imageMeta":{"width":2000,"height":1333},"childImageSharp":{"fluid":{"base64":"data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAANABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAIDBf/EABUBAQEAAAAAAAAAAAAAAAAAAAAB/9oADAMBAAIQAxAAAAHJai1MBP/EABcQAAMBAAAAAAAAAAAAAAAAAAABEBH/2gAIAQEAAQUCuDU//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPwE//8QAFREBAQAAAAAAAAAAAAAAAAAAEBH/2gAIAQIBAT8Bh//EABQQAQAAAAAAAAAAAAAAAAAAACD/2gAIAQEABj8CX//EABgQAQEBAQEAAAAAAAAAAAAAAAABESFR/9oACAEBAAE/IYy+rHKDH//aAAwDAQACAAMAAAAQC9//xAAVEQEBAAAAAAAAAAAAAAAAAAAQEf/aAAgBAwEBPxCn/8QAFREBAQAAAAAAAAAAAAAAAAAAARD/2gAIAQIBAT8QUT//xAAaEAADAQADAAAAAAAAAAAAAAAAAREhQWFx/9oACAEBAAE/EMY0neijzwMrrVEm7auUQPNGlP/Z","aspectRatio":1.5028901734104045,"src":"/static/7140ea32e1157ba61402d5d67ab846d4/d5c54/photo-1581276879432-15e50529f34b.jpg","srcSet":"/static/7140ea32e1157ba61402d5d67ab846d4/65d8c/photo-1581276879432-15e50529f34b.jpg 260w,\n/static/7140ea32e1157ba61402d5d67ab846d4/c5f21/photo-1581276879432-15e50529f34b.jpg 520w,\n/static/7140ea32e1157ba61402d5d67ab846d4/d5c54/photo-1581276879432-15e50529f34b.jpg 1040w,\n/static/7140ea32e1157ba61402d5d67ab846d4/81a53/photo-1581276879432-15e50529f34b.jpg 1560w,\n/static/7140ea32e1157ba61402d5d67ab846d4/4e5f3/photo-1581276879432-15e50529f34b.jpg 2000w","srcWebp":"/static/7140ea32e1157ba61402d5d67ab846d4/e4875/photo-1581276879432-15e50529f34b.webp","srcSetWebp":"/static/7140ea32e1157ba61402d5d67ab846d4/dc8f3/photo-1581276879432-15e50529f34b.webp 260w,\n/static/7140ea32e1157ba61402d5d67ab846d4/2db4b/photo-1581276879432-15e50529f34b.webp 520w,\n/static/7140ea32e1157ba61402d5d67ab846d4/e4875/photo-1581276879432-15e50529f34b.webp 1040w,\n/static/7140ea32e1157ba61402d5d67ab846d4/f5845/photo-1581276879432-15e50529f34b.webp 1560w,\n/static/7140ea32e1157ba61402d5d67ab846d4/49d6b/photo-1581276879432-15e50529f34b.webp 2000w","sizes":"(max-width: 1040px) 100vw, 1040px"}}}},"tags":[{"slug":"react","url":"https://backend.shahednasser.com/tag/react/","name":"React","visibility":"public","feature_image":"https://images.unsplash.com/photo-1581276879432-15e50529f34b?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=MnwxMTc3M3wwfDF8c2VhcmNofDN8fHJlYWN0fGVufDB8fHx8MTYyMjYzMzI0MA&ixlib=rb-1.2.1&q=80&w=2000","description":"Learn more about React through tutorials, articles, and tips.","meta_title":null,"meta_description":null,"featureImageSharp":null},{"slug":"js","url":"https://backend.shahednasser.com/tag/js/","name":"Javascript","visibility":"public","feature_image":"https://backend.shahednasser.com/content/images/2022/01/photo-1592609931095-54a2168ae893-2.jpeg","description":"Learn more about Javascript through tutorials, articles, and tips.","meta_title":null,"meta_description":"Learn more about Javascript through tutorials, articles and tips.","featureImageSharp":null}],"plaintext":"React Query (now rebranded to TanStack Query) is a React library used to make fetching and manipulating server-side data easier. Using React Query, you can implement, along with data fetching, caching, and synchronization of your data with the server.\n\nIn this tutorial, you'll build a simple Node.js server and then learn how to interact with it on a React website using React Query.\n\nPlease note that this version uses v4 of React Query which is now named TanStack Query.\n\nYou can find the code for this tutorial in this GitHub repository.\n\n\nPrerequisites\n\nBefore starting with this tutorial make sure you have Node.js installed. You need at least version 14.\n\n\nServer Setup\n\nIn this section, you'll set up a simple Node.js server with an SQLite database. The server has 3 endpoints to fetch, add, and delete notes.\n\nIf you already have a server you can skip this section and go to the Website Setup section.\n\n\nCreate Server Project\n\nCreate a new directory called server then initialize a new project using NPM:\n\nmkdir server\ncd server\nnpm init -y\n\n\nInstall Dependencies\n\nThen, install the packages you'll need for the development of the server:\n\nnpm i express cors body-parser sqlite3 nodemon\n\nHere's what each of the packages is for:\n\n 1. express to create a server using Express.\n 2. cors is an Express middleware used to handle CORS on your server.\n 3. body-parser is an Express middleware used to parse the body of a request.\n 4. sqlite3 is an SQLite database adapter for Node.js.\n 5. nodemon is a library used to restart the server whenever new changes occur to the files.\n\n\nCreate Server\n\nCreate the file index.js with the following content:\n\nconst express = require('express');\n\nconst app = express();\nconst port = 3001;\nconst cors = require('cors');\nconst sqlite3 = require('sqlite3').verbose();\nconst bodyParser = require('body-parser');\n\napp.use(bodyParser.json());\napp.use(cors());\n\napp.listen(port, () => {\n  console.log(`Notes app listening on port ${port}`);\n});\n\nThis initializes the server using Express on port 3001. It also uses the cors and body-parser middleware.\n\nThen, in package.json add a new script start to run the server:\n\n  \"scripts\": {\n    \"start\": \"nodemon index.js\"\n  },\n\n\nInitialize the Database\n\nIn index.js before app.listen add the following code:\n\nconst db = new sqlite3.Database('data.db', (err) => {\n  if (err) {\n    throw err;\n  }\n\n  // create tables if they don't exist\n  db.serialize(() => {\n    db.run(`CREATE TABLE IF NOT EXISTS notes (id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT, content TEXT, \n      created_at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP)`);\n  });\n});\n\nThis creates a new database if it doesn't exist in the file data.db. Then, if the notes table doesn't exist on the database it creates it as well.\n\n\nAdd Endpoints\n\nFollowing the database code, add the following code to add the endpoints:\n\napp.get('/notes', (req, res) => {\n  db.all('SELECT * FROM notes', (err, rows) => {\n    if (err) {\n      console.error(err);\n      return res.status(500).json({ success: false, message: 'An error occurred, please try again later' });\n    }\n\n    return res.json({ success: true, data: rows });\n  });\n});\n\napp.get('/notes/:id', (req, res) => {\n  db.get('SELECT * FROM notes WHERE id = ?', req.params.id, (err, row) => {\n    if (err) {\n      console.error(err);\n      return res.status(500).json({ success: false, message: 'An error occurred, please try again later' });\n    }\n\n    if (!row) {\n      return res.status(404).json({ success: false, message: 'Note does not exist' });\n    }\n\n    return res.json({ success: true, data: row });\n  });\n});\n\napp.post('/notes', (req, res) => {\n  const { title, content } = req.body;\n\n  if (!title || !content) {\n    return res.status(400).json({ success: false, message: 'title and content are required' });\n  }\n\n  db.run('INSERT INTO notes (title, content) VALUES (?, ?)', [title, content], function (err) {\n    if (err) {\n      console.error(err);\n      return res.status(500).json({ success: false, message: 'An error occurred, please try again later' });\n    }\n\n    return res.json({\n      success: true,\n      data: {\n        id: this.lastID,\n        title,\n        content,\n      },\n    });\n  });\n});\n\napp.delete('/notes/:id', (req, res) => {\n  const { id } = req.params;\n\n  db.get('SELECT * FROM notes WHERE id = ?', [id], (err, row) => {\n    if (err) {\n      console.error(err);\n      return res.status(500).json({ success: false, message: 'An error occurred, please try again later' });\n    }\n\n    if (!row) {\n      return res.status(404).json({ success: false, message: 'Note does not exist' });\n    }\n\n    db.run('DELETE FROM notes WHERE id = ?', [id], (error) => {\n      if (error) {\n        console.error(error);\n        return res.status(500).json({ success: false, message: 'An error occurred, please try again later' });\n      }\n\n      return res.json({ success: true, message: 'Note deleted successfully' });\n    });\n  });\n});\n\nBriefly, this creates 4 endpoints:\n\n 1. /notes endpoint of the method GET to fetch all notes.\n 2. /notes/:id endpoint of the method GET to fetch a note by an ID.\n 3. /notes endpoint of the method POST to add a note.\n 4. /notes/:id endpoint of the method DELETE to delete a note.\n\n\nTest Server\n\nRun the following command to start the server:\n\nnpm start\n\nThis starts the server on port 3001. You can test it out by sending a request to localhost:3001/notes.\n\n\nWebsite Setup\n\nIn this section, you'll create the website with Create React App (CRA). This is where you'll make use of React Query.\n\n\nCreate Website Project\n\nTo create a new React app, run the following command in a different directory:\n\nnpx create-react-app website\n\nThis creates a new React app in the directory website.\n\n\nInstall Dependencies\n\nRun the following command to change to the website directory and install the necessary dependencies for the website:\n\ncd website\nnpm i @tanstack/react-query tailwindcss postcss autoprefixer @tailwindcss/typography @heroicons/react @windmill/react-ui\n\nThe @tanstack/react-query library is the React Query library which is now named TanStack Query. The other libraries are Tailwind CSS related libraries to add styling to the website.\n\n\nTailwind CSS Setup\n\nThis section is optional and is only used to set up Tailwind CSS.\n\nCreate the file postcss.config.js with the following content:\n\nmodule.exports = {\n  plugins: {\n    tailwindcss: {},\n    autoprefixer: {},\n  },\n}\n\n\nAlso, create the file tailwind.config.js with the following content:\n\n/** @type {import('tailwindcss').Config} */\nmodule.exports = {\n  content: [\n    \"./src/**/*.{js,jsx,ts,tsx}\",\n  ],\n  theme: {\n    extend: {},\n  },\n  plugins: [\n    require('@tailwindcss/typography')\n  ],\n}\n\n\nThen, create the file src/index.css with the following content:\n\n@tailwind base;\n@tailwind components;\n@tailwind utilities;\n\nFinally, in index.js import src/index.css at the beginning of the file:\n\nimport './index.css';\n\n\nUse QueryClientProvider\n\nTo use the React Query client in all of your components, you must use it at a high level in your website's components hierarchy. The best place to put it is in src/index.js which wraps up your entire website's components.\n\nIn src/index.js add the following imports at the beginning of the file:\n\nimport {\n  QueryClient,\n  QueryClientProvider,\n} from '@tanstack/react-query'\n\nThen, initialize a new Query client:\n\nconst queryClient = new QueryClient()\n\nFinally, change the parameter passed to root.render:\n\nroot.render(\n  <QueryClientProvider client={queryClient}>\n    <App />\n  </QueryClientProvider>\n);\n\nThis wraps the App component which holds the rest of the website's components with QueryClientProvider. This provider accepts the prop client which is an instance of QueryClient.\n\nNow, all components within the website will have access to the Query Client which is used to fetch, cache, and manipulate the server data.\n\n\nImplement Display Notes\n\nFetching data from the server is an act of performing a query. Therefore, you'll use useQuery in this section.\n\nYou'll display notes in the App component. These notes are fetched from the server using the /notes endpoint.\n\nReplace the content of app.js with the following content:\n\nimport { PlusIcon, RefreshIcon } from '@heroicons/react/solid'\nimport { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'\n\nfunction App() {\n  const { isLoading, isError, data, error } = useQuery(['notes'], fetchNotes)\n\n  function fetchNotes () {\n    return fetch('http://localhost:3001/notes')\n    .then((response) => response.json())\n    .then(({ success, data }) => {\n      if (!success) {\n        throw new Error ('An error occurred while fetching notes');\n      }\n      return data;\n    })\n  }\n\n  return (\n    <div className=\"w-screen h-screen overflow-x-hidden bg-red-400 flex flex-col justify-center items-center\">\n      <div className='bg-white w-full md:w-1/2 p-5 text-center rounded shadow-md text-gray-800 prose'>\n        <h1>Notes</h1>\n        {isLoading && <RefreshIcon className=\"w-10 h-10 animate-spin mx-auto\"></RefreshIcon>}\n        {isError && <span className='text-red'>{error.message ? error.message : error}</span>}\n        {!isLoading && !isError && data && !data.length && <span className='text-red-400'>You have no notes</span>}\n        {data && data.length > 0 && data.map((note, index) => (\n          <div key={note.id} className={`text-left ${index !== data.length - 1 ? 'border-b pb-2' : ''}`}>\n            <h2>{note.title}</h2>\n            <p>{note.content}</p>\n            <span>\n              <button className='link text-gray-400'>Delete</button>\n            </span>\n          </div>\n        ))}\n      </div>\n      <button className=\"mt-2 bg-gray-700 hover:bg-gray-600 rounded-full text-white p-3\">\n        <PlusIcon className='w-5 h-5'></PlusIcon>\n      </button>\n    </div>\n  );\n}\n\nexport default App;\n\nHere's briefly what's going on in this code snippet:\n\n 1. You use useQuery to fetch the notes. The first parameter it accepts is a unique key used for caching. The second parameter is the function used to fetch the data. You pass it the fetchNotes function.\n 2. useQuery returns an object that holds many variables. Here, you use 4 of them: isLoading is a boolean value that determines whether the data is currently being fetched; isError is a boolean value that determines if an error occurred. data is the data that is fetched from the server; and error is the error message if isError is true.\n 3. The fetchNotes function must return a promise that either resolves data or throws an error. In the function, you send a GET request to localhost:3001/notes to fetch the notes. If the data is fetched successfully it is returned in the then fulfillment function.\n 4. In the returned JSX, if isLoading is true, a loading icon is shown. If isError is true, an error message is shown. If data is fetched successfully and has any data in it, the notes are rendered.\n 5. You also show a button with a plus icon to add new notes. You'll implement this later.\n\n\nTest Displaying Notes\n\nTo test out what you've implemented so far, make sure your server is still running, then start your React app server with the following command:\n\nnpm start\n\nThis runs your React app on localhost:3000 by default. If you open it in your browser, you'll see a loading icon at first then you'll see no notes as you haven't added any yet.\n\n\nImplement Add Notes Functionality\n\nAdding a note is an act of mutation on the server data. Therefore, you'll be using the useMutation hook in this section.\n\nYou'll create a separate component that shows the form used to add a note.\n\nCreate the file src/form.js with the following content:\n\nimport { useMutation, useQueryClient } from '@tanstack/react-query'\n\nimport { useState } from 'react'\n\nexport default function Form ({ isOpen, setIsOpen }) {\n  const [title, setTitle] = useState(\"\")\n  const [content, setContent] = useState(\"\")\n  const queryClient = useQueryClient()\n\n  const mutation = useMutation(insertNote, {\n    onSuccess: () => {\n      setTitle(\"\")\n      setContent(\"\")\n    }\n  })\n\n  function closeForm (e) {\n    e.preventDefault()\n    setIsOpen(false)\n  }\n\n  function insertNote () {\n    return fetch(`http://localhost:3001/notes`, {\n      method: 'POST',\n      headers: {\n        'Content-Type': 'application/json'\n      },\n      body: JSON.stringify({\n        title,\n        content\n      })\n    })\n    .then((response) => response.json())\n    .then(({ success, data }) => {\n      if (!success) {\n        throw new Error(\"An error occured\")\n      }\n      \n      setIsOpen(false)\n      queryClient.setQueriesData('notes', (old) => [...old, data])\n    })\n  }\n\n  function handleSubmit (e) {\n    e.preventDefault()\n    mutation.mutate()\n  }\n\n  return (\n    <div className={`absolute w-full h-full top-0 left-0 z-50 flex justify-center items-center ${!isOpen ? 'hidden' : ''}`}>\n      <div className='bg-black opacity-50 absolute w-full h-full top-0 left-0'></div>\n      <form className='bg-white w-full md:w-1/2 p-5 rounded shadow-md text-gray-800 prose relative' \n        onSubmit={handleSubmit}>\n        <h2 className='text-center'>Add Note</h2>\n        {mutation.isError && <span className='block mb-2 text-red-400'>{mutation.error.message ? mutation.error.message : mutation.error}</span>}\n        <input type=\"text\" placeholder='Title' className='rounded-sm w-full border px-2' \n          value={title} onChange={(e) => setTitle(e.target.value)} />\n        <textarea onChange={(e) => setContent(e.target.value)} \n          className=\"rounded-sm w-full border px-2 mt-2\" placeholder='Content' value={content}></textarea>\n        <div>\n          <button type=\"submit\" className='mt-2 bg-red-400 hover:bg-red-600 text-white p-3 rounded mr-2 disabled:pointer-events-none' \n            disabled={mutation.isLoading}>\n            Add</button>\n          <button className='mt-2 bg-gray-700 hover:bg-gray-600 text-white p-3 rounded'\n            onClick={closeForm}>Cancel</button>\n        </div>\n      </form>\n    </div>\n  )\n}\n\nHere's a brief explanation of this form\n\n 1. This form acts as a pop-up. It accepts isOpen and setIsOpen props to determine when the form is opened and handle closing it.\n 2. You use useQueryClient to get access to the Query Client. This is necessary to perform a mutation.\n 3. To handle adding a note on your server and keep all data in your query client synced, you must the useMutation hook.\n 4. The useMutation hook accepts 2 parameters. Thie first one is the function that will handle the mutation, which in this case is insertNote. The second parameter is an object of options. You pass it one option onSuccess which is a function that runs if the mutation is performed successfully. You use this to reset the title and content fields of the form.\n 5. In insertNote, you send a POST request to localhost:3001/notes and pass in the body the title and content of the note to be created. If the success body parameter returned from the server is false, an error is thrown to signal that the mutation failed.\n 6. If the note is added successfully, you change the cached value of the notes key using the queryClient.setQueriesData method. This method accepts the key as a first parameter and the new data associated with that key as a second parameter. This updates the data everywhere it's used on your website.\n 7. In this component you display a form with 2 fields: title and content. In the form, you check if an error occurs using mutation.isError and get access to the error using mutation.error.\n 8. You handle form submission in the handleSubmit function. Here, you trigger the mutation using mutation.mutate. This is where the insertNote function is triggered to add a new note.\n\nThen, in src/app.js add the following imports at the beginning of the file:\n\nimport Form from './form'\nimport { useState } from 'react'\n\nThen, at the beginning of the component add a new state variable to manage wheter the form is opened or not:\n\nconst [isOpen, setIsOpen] = useState(false)\n\nNext, add a new function addNote that just uses setIsOpen to open the form:\n\nfunction addNote () {\n    setIsOpen(true)\n}\n\nFinally, in the returned JSX, replace the button with the plus icon with the following:\n\n<button className=\"mt-2 bg-gray-700 hover:bg-gray-600 rounded-full text-white p-3\" onClick={addNote}>\n    <PlusIcon className='w-5 h-5'></PlusIcon>\n</button>\n<Form isOpen={isOpen} setIsOpen={setIsOpen} />\n\nThis sets the onClick handler of the button to addNote. It also adds the Form component you created earlier as a child component of App.\n\n\nTest Adding a Note\n\nRerun your server and React app if they're not running. Then, open the website again at localhost:3000. Click on the plus button and a pop up will open with the form to add a new note.\n\nEnter a random title and content then click Add. The pop up form will then close and you can see the new note added.\n\n\nImplement Delete Note Functionality\n\nThe last functionality you'll add is deleting notes. Deleting a note is another act of mutation as it manipulates the server's data.\n\nAt the beginning of the App component in src/app.js add the following code:\n\nconst queryClient = useQueryClient()\nconst mutation = useMutation(deleteNote, {\n    onSuccess: () => queryClient.invalidateQueries('notes')\n})\n\nHere, you get access to the query client using useQueryClient. Then, you create a new mutation using useMutation. You pass it the function deleteNote (which you'll create next) as a first parameter and an object of options.\n\nTo the onSuccess option you pass a function that does one thing. It executes the method queryClient.invalidateQueries. This method marks the cached data for a specific key as outdated, which triggers retrieving the data again.\n\nSo, once a note is deleted, the query you created earlier that executes the function fetchNotes will be triggered and the notes will be fetched again. If you had created other queries on your website that use the same key notes, they'll also be triggered to update their data.\n\nNext, add the function deleteNote in the App component in the same file:\n\nfunction deleteNote (note) {\n    return fetch(`http://localhost:3001/notes/${note.id}`, {\n      method: 'DELETE'\n    })\n    .then((response) => response.json())\n    .then(({ success, message }) => {\n      if (!success) {\n        throw new Error(message);\n      }\n\n      alert(message);\n    })\n  }\n\nThis function receives the note to be deleted as a parameter. It sends a DELETE request to localhost:3001/notes/:id. If the success body parameter of the response is false, an error is thrown. Otherwise, only an alert is shown.\n\nThen, in the returned JSX of the App component, change how the loading icon and error where shown previously to the following:\n\n{(isLoading || mutation.isLoading) && <RefreshIcon className=\"w-10 h-10 animate-spin mx-auto\"></RefreshIcon>}\n{(isError || mutation.isError) && <span className='text-red'>{error ? (error.message ? error.message : error) : mutation.error.message}</span>}\n\nThis shows the loading icon or the error message for both the query that fetches the notes and the mutation that handles deleting a note.\n\nFinally, find the delete button of a note and add an onClick handler:\n\n<button className='link text-gray-400' onClick={() => mutation.mutate(note)}>Delete</button>\n\nOn click, the mutation responsible for deleting the note is triggered using mutation.mutate. You pass it the note to delete which is the current note in a map loop.\n\n\nTest Deleting a Note\n\nRerun your server and React app if they're not running. Then, open the website again at localhost:3000. Click the Delete link for any of your notes. If the note is deleted successfully, an alert will be shown.\n\nAfter closing the alert, the notes will be fetched again and displayed, if there are any other notes.\n\n\nConclusion\n\nUsing React (TanStack) Query, you can easily handle server data fetching and manipulation on your website with advanced features such as caching and synchronization across your React app.\n\nMake sure to check out the official documentation to learn more about what you can do with React Query.","html":"<p>React Query (now rebranded to TanStack Query) is a React library used to make fetching and manipulating server-side data easier. Using React Query, you can implement, along with data fetching, caching, and synchronization of your data with the server.</p><p>In this tutorial, you'll build a simple Node.js server and then learn how to interact with it on a React website using React Query.</p><p>Please note that this version uses v4 of React Query which is now named TanStack Query.</p><p>You can find the code for this tutorial in <a href=\"https://github.com/shahednasser/react-query-tutorial\">this GitHub repository</a>.</p><h2 id=\"prerequisites\">Prerequisites</h2><p> Before starting with this tutorial make sure you have <a href=\"https://nodejs.org/en/\">Node.js installed</a>. You need at least version 14.</p><h2 id=\"server-setup\">Server Setup</h2><p>In this section, you'll set up a simple Node.js server with an SQLite database. The server has 3 endpoints to fetch, add, and delete notes.</p><p>If you already have a server you can skip this section and go to the Website Setup section.</p><h3 id=\"create-server-project\">Create Server Project</h3><p>Create a new directory called <code>server</code> then initialize a new project using NPM:</p><pre><code class=\"language-bash\">mkdir server\ncd server\nnpm init -y</code></pre><h3 id=\"install-dependencies\">Install Dependencies</h3><p>Then, install the packages you'll need for the development of the server:</p><pre><code class=\"language-bash\">npm i express cors body-parser sqlite3 nodemon</code></pre><p>Here's what each of the packages is for:</p><ol><li><code>express</code> to create a server using <a href=\"https://expressjs.com/\">Express</a>.</li><li><code>cors</code> is an Express middleware used to handle <a href=\"https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS\">CORS</a> on your server.</li><li><code>body-parser</code> is an Express middleware used to parse the body of a request.</li><li><code>sqlite3</code> is an SQLite database adapter for Node.js.</li><li><code>nodemon</code> is a library used to restart the server whenever new changes occur to the files.</li></ol><h3 id=\"create-server\">Create Server</h3><p>Create the file <code>index.js</code> with the following content:</p><pre><code class=\"language-js\">const express = require('express');\n\nconst app = express();\nconst port = 3001;\nconst cors = require('cors');\nconst sqlite3 = require('sqlite3').verbose();\nconst bodyParser = require('body-parser');\n\napp.use(bodyParser.json());\napp.use(cors());\n\napp.listen(port, () =&gt; {\n  console.log(`Notes app listening on port ${port}`);\n});</code></pre><p>This initializes the server using Express on port <code>3001</code>. It also uses the <code>cors</code> and <code>body-parser</code> middleware.</p><p>Then, in <code>package.json</code> add a new script <code>start</code> to run the server:</p><pre><code class=\"language-json\">  \"scripts\": {\n    \"start\": \"nodemon index.js\"\n  },</code></pre><h3 id=\"initialize-the-database\">Initialize the Database</h3><p>In <code>index.js</code> before <code>app.listen</code> add the following code:</p><pre><code class=\"language-js\">const db = new sqlite3.Database('data.db', (err) =&gt; {\n  if (err) {\n    throw err;\n  }\n\n  // create tables if they don't exist\n  db.serialize(() =&gt; {\n    db.run(`CREATE TABLE IF NOT EXISTS notes (id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT, content TEXT, \n      created_at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP)`);\n  });\n});</code></pre><p>This creates a new database if it doesn't exist in the file <code>data.db</code>. Then, if the <code>notes</code> table doesn't exist on the database it creates it as well.</p><h3 id=\"add-endpoints\">Add Endpoints</h3><p>Following the database code, add the following code to add the endpoints:</p><pre><code class=\"language-js\">app.get('/notes', (req, res) =&gt; {\n  db.all('SELECT * FROM notes', (err, rows) =&gt; {\n    if (err) {\n      console.error(err);\n      return res.status(500).json({ success: false, message: 'An error occurred, please try again later' });\n    }\n\n    return res.json({ success: true, data: rows });\n  });\n});\n\napp.get('/notes/:id', (req, res) =&gt; {\n  db.get('SELECT * FROM notes WHERE id = ?', req.params.id, (err, row) =&gt; {\n    if (err) {\n      console.error(err);\n      return res.status(500).json({ success: false, message: 'An error occurred, please try again later' });\n    }\n\n    if (!row) {\n      return res.status(404).json({ success: false, message: 'Note does not exist' });\n    }\n\n    return res.json({ success: true, data: row });\n  });\n});\n\napp.post('/notes', (req, res) =&gt; {\n  const { title, content } = req.body;\n\n  if (!title || !content) {\n    return res.status(400).json({ success: false, message: 'title and content are required' });\n  }\n\n  db.run('INSERT INTO notes (title, content) VALUES (?, ?)', [title, content], function (err) {\n    if (err) {\n      console.error(err);\n      return res.status(500).json({ success: false, message: 'An error occurred, please try again later' });\n    }\n\n    return res.json({\n      success: true,\n      data: {\n        id: this.lastID,\n        title,\n        content,\n      },\n    });\n  });\n});\n\napp.delete('/notes/:id', (req, res) =&gt; {\n  const { id } = req.params;\n\n  db.get('SELECT * FROM notes WHERE id = ?', [id], (err, row) =&gt; {\n    if (err) {\n      console.error(err);\n      return res.status(500).json({ success: false, message: 'An error occurred, please try again later' });\n    }\n\n    if (!row) {\n      return res.status(404).json({ success: false, message: 'Note does not exist' });\n    }\n\n    db.run('DELETE FROM notes WHERE id = ?', [id], (error) =&gt; {\n      if (error) {\n        console.error(error);\n        return res.status(500).json({ success: false, message: 'An error occurred, please try again later' });\n      }\n\n      return res.json({ success: true, message: 'Note deleted successfully' });\n    });\n  });\n});</code></pre><p>Briefly, this creates 4 endpoints:</p><ol><li><code>/notes</code> endpoint of the method <code>GET</code> to fetch all notes.</li><li><code>/notes/:id</code> endpoint of the method <code>GET</code> to fetch a note by an ID.</li><li><code>/notes</code> endpoint of the method <code>POST</code> to add a note.</li><li><code>/notes/:id</code> endpoint of the method <code>DELETE</code> to delete a note.</li></ol><h3 id=\"test-server\">Test Server</h3><p>Run the following command to start the server:</p><pre><code class=\"language-bash\">npm start</code></pre><p>This starts the server on port <code>3001</code>. You can test it out by sending a request to <code>localhost:3001/notes</code>.</p><h2 id=\"website-setup\">Website Setup</h2><p>In this section, you'll create the website with Create React App (CRA). This is where you'll make use of React Query.</p><h3 id=\"create-website-project\">Create Website Project</h3><p>To create a new React app, run the following command in a different directory:</p><pre><code class=\"language-bash\">npx create-react-app website</code></pre><p>This creates a new React app in the directory <code>website</code>.</p><h3 id=\"install-dependencies-1\">Install Dependencies</h3><p>Run the following command to change to the <code>website</code> directory and install the necessary dependencies for the website:</p><pre><code class=\"language-bash\">cd website\nnpm i @tanstack/react-query tailwindcss postcss autoprefixer @tailwindcss/typography @heroicons/react @windmill/react-ui</code></pre><p>The <code>@tanstack/react-query</code> library is the React Query library which is now named TanStack Query. The other libraries are <a href=\"https://tailwindcss.com/\">Tailwind CSS</a> related libraries to add styling to the website.</p><h3 id=\"tailwind-css-setup\">Tailwind CSS Setup</h3><p>This section is optional and is only used to set up Tailwind CSS.</p><p>Create the file <code>postcss.config.js</code> with the following content:</p><pre><code class=\"language-js\">module.exports = {\n  plugins: {\n    tailwindcss: {},\n    autoprefixer: {},\n  },\n}\n</code></pre><p>Also, create the file <code>tailwind.config.js</code> with the following content:</p><pre><code class=\"language-js\">/** @type {import('tailwindcss').Config} */\nmodule.exports = {\n  content: [\n    \"./src/**/*.{js,jsx,ts,tsx}\",\n  ],\n  theme: {\n    extend: {},\n  },\n  plugins: [\n    require('@tailwindcss/typography')\n  ],\n}\n</code></pre><p>Then, create the file <code>src/index.css</code> with the following content:</p><pre><code class=\"language-css\">@tailwind base;\n@tailwind components;\n@tailwind utilities;</code></pre><p>Finally, in <code>index.js</code> import <code>src/index.css</code> at the beginning of the file:</p><pre><code class=\"language-js\">import './index.css';</code></pre><h3 id=\"use-queryclientprovider\">Use QueryClientProvider</h3><p>To use the React Query client in all of your components, you must use it at a high level in your website's components hierarchy. The best place to put it is in <code>src/index.js</code> which wraps up your entire website's components.</p><p>In <code>src/index.js</code> add the following imports at the beginning of the file:</p><pre><code class=\"language-js\">import {\n  QueryClient,\n  QueryClientProvider,\n} from '@tanstack/react-query'</code></pre><p>Then, initialize a new Query client:</p><pre><code class=\"language-js\">const queryClient = new QueryClient()</code></pre><p>Finally, change the parameter passed to <code>root.render</code>:</p><pre><code class=\"language-js\">root.render(\n  &lt;QueryClientProvider client={queryClient}&gt;\n    &lt;App /&gt;\n  &lt;/QueryClientProvider&gt;\n);</code></pre><p>This wraps the <code>App</code> component which holds the rest of the website's components with <code>QueryClientProvider</code>. This provider accepts the prop <code>client</code> which is an instance of <code>QueryClient</code>.</p><p>Now, all components within the website will have access to the Query Client which is used to fetch, cache, and manipulate the server data.</p><h3 id=\"implement-display-notes\">Implement Display Notes</h3><p>Fetching data from the server is an act of performing a query. Therefore, you'll use <code>useQuery</code> in this section.</p><p>You'll display notes in the <code>App</code> component. These notes are fetched from the server using the <code>/notes</code> endpoint.</p><p>Replace the content of <code>app.js</code> with the following content:</p><pre><code class=\"language-js\">import { PlusIcon, RefreshIcon } from '@heroicons/react/solid'\nimport { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'\n\nfunction App() {\n  const { isLoading, isError, data, error } = useQuery(['notes'], fetchNotes)\n\n  function fetchNotes () {\n    return fetch('http://localhost:3001/notes')\n    .then((response) =&gt; response.json())\n    .then(({ success, data }) =&gt; {\n      if (!success) {\n        throw new Error ('An error occurred while fetching notes');\n      }\n      return data;\n    })\n  }\n\n  return (\n    &lt;div className=\"w-screen h-screen overflow-x-hidden bg-red-400 flex flex-col justify-center items-center\"&gt;\n      &lt;div className='bg-white w-full md:w-1/2 p-5 text-center rounded shadow-md text-gray-800 prose'&gt;\n        &lt;h1&gt;Notes&lt;/h1&gt;\n        {isLoading &amp;&amp; &lt;RefreshIcon className=\"w-10 h-10 animate-spin mx-auto\"&gt;&lt;/RefreshIcon&gt;}\n        {isError &amp;&amp; &lt;span className='text-red'&gt;{error.message ? error.message : error}&lt;/span&gt;}\n        {!isLoading &amp;&amp; !isError &amp;&amp; data &amp;&amp; !data.length &amp;&amp; &lt;span className='text-red-400'&gt;You have no notes&lt;/span&gt;}\n        {data &amp;&amp; data.length &gt; 0 &amp;&amp; data.map((note, index) =&gt; (\n          &lt;div key={note.id} className={`text-left ${index !== data.length - 1 ? 'border-b pb-2' : ''}`}&gt;\n            &lt;h2&gt;{note.title}&lt;/h2&gt;\n            &lt;p&gt;{note.content}&lt;/p&gt;\n            &lt;span&gt;\n              &lt;button className='link text-gray-400'&gt;Delete&lt;/button&gt;\n            &lt;/span&gt;\n          &lt;/div&gt;\n        ))}\n      &lt;/div&gt;\n      &lt;button className=\"mt-2 bg-gray-700 hover:bg-gray-600 rounded-full text-white p-3\"&gt;\n        &lt;PlusIcon className='w-5 h-5'&gt;&lt;/PlusIcon&gt;\n      &lt;/button&gt;\n    &lt;/div&gt;\n  );\n}\n\nexport default App;</code></pre><p>Here's briefly what's going on in this code snippet:</p><ol><li>You use <code>useQuery</code> to fetch the notes. The first parameter it accepts is a unique key used for caching. The second parameter is the function used to fetch the data. You pass it the <code>fetchNotes</code> function.</li><li><code>useQuery</code> returns an object that holds <a href=\"https://tanstack.com/query/v4/docs/reference/useQuery\">many variables</a>. Here, you use 4 of them: <code>isLoading</code> is a boolean value that determines whether the data is currently being fetched; <code>isError</code> is a boolean value that determines if an error occurred. <code>data</code> is the data that is fetched from the server; and <code>error</code> is the error message if <code>isError</code> is true.</li><li>The <code>fetchNotes</code> function must return a promise that either resolves data or throws an error. In the function, you send a <code>GET</code> request to <code>localhost:3001/notes</code> to fetch the notes. If the data is fetched successfully it is returned in the <code>then</code> fulfillment function. </li><li>In the returned JSX, if <code>isLoading</code> is true, a loading icon is shown. If <code>isError</code> is true, an error message is shown. If <code>data</code> is fetched successfully and has any data in it, the notes are rendered.</li><li>You also show a button with a plus icon to add new notes. You'll implement this later.</li></ol><h3 id=\"test-displaying-notes\">Test Displaying Notes</h3><p>To test out what you've implemented so far, make sure your server is still running, then start your React app server with the following command:</p><pre><code class=\"language-bash\">npm start</code></pre><p>This runs your React app on <code>localhost:3000</code> by default. If you open it in your browser, you'll see a loading icon at first then you'll see no notes as you haven't added any yet.</p><figure class=\"kg-card kg-image-card\"><img src=\"https://backend.shahednasser.com/content/images/2022/07/Screen-Shot-2022-06-28-at-9.10.04-PM.png\" class=\"kg-image\" alt loading=\"lazy\" width=\"1446\" height=\"490\" srcset=\"https://backend.shahednasser.com/content/images/size/w600/2022/07/Screen-Shot-2022-06-28-at-9.10.04-PM.png 600w, https://backend.shahednasser.com/content/images/size/w1000/2022/07/Screen-Shot-2022-06-28-at-9.10.04-PM.png 1000w, https://backend.shahednasser.com/content/images/2022/07/Screen-Shot-2022-06-28-at-9.10.04-PM.png 1446w\" sizes=\"(min-width: 720px) 720px\"></figure><h3 id=\"implement-add-notes-functionality\">Implement Add Notes Functionality</h3><p>Adding a note is an act of mutation on the server data. Therefore, you'll be using the <code>useMutation</code> hook in this section.</p><p>You'll create a separate component that shows the form used to add a note.</p><p>Create the file <code>src/form.js</code> with the following content:</p><pre><code class=\"language-js\">import { useMutation, useQueryClient } from '@tanstack/react-query'\n\nimport { useState } from 'react'\n\nexport default function Form ({ isOpen, setIsOpen }) {\n  const [title, setTitle] = useState(\"\")\n  const [content, setContent] = useState(\"\")\n  const queryClient = useQueryClient()\n\n  const mutation = useMutation(insertNote, {\n    onSuccess: () =&gt; {\n      setTitle(\"\")\n      setContent(\"\")\n    }\n  })\n\n  function closeForm (e) {\n    e.preventDefault()\n    setIsOpen(false)\n  }\n\n  function insertNote () {\n    return fetch(`http://localhost:3001/notes`, {\n      method: 'POST',\n      headers: {\n        'Content-Type': 'application/json'\n      },\n      body: JSON.stringify({\n        title,\n        content\n      })\n    })\n    .then((response) =&gt; response.json())\n    .then(({ success, data }) =&gt; {\n      if (!success) {\n        throw new Error(\"An error occured\")\n      }\n      \n      setIsOpen(false)\n      queryClient.setQueriesData('notes', (old) =&gt; [...old, data])\n    })\n  }\n\n  function handleSubmit (e) {\n    e.preventDefault()\n    mutation.mutate()\n  }\n\n  return (\n    &lt;div className={`absolute w-full h-full top-0 left-0 z-50 flex justify-center items-center ${!isOpen ? 'hidden' : ''}`}&gt;\n      &lt;div className='bg-black opacity-50 absolute w-full h-full top-0 left-0'&gt;&lt;/div&gt;\n      &lt;form className='bg-white w-full md:w-1/2 p-5 rounded shadow-md text-gray-800 prose relative' \n        onSubmit={handleSubmit}&gt;\n        &lt;h2 className='text-center'&gt;Add Note&lt;/h2&gt;\n        {mutation.isError &amp;&amp; &lt;span className='block mb-2 text-red-400'&gt;{mutation.error.message ? mutation.error.message : mutation.error}&lt;/span&gt;}\n        &lt;input type=\"text\" placeholder='Title' className='rounded-sm w-full border px-2' \n          value={title} onChange={(e) =&gt; setTitle(e.target.value)} /&gt;\n        &lt;textarea onChange={(e) =&gt; setContent(e.target.value)} \n          className=\"rounded-sm w-full border px-2 mt-2\" placeholder='Content' value={content}&gt;&lt;/textarea&gt;\n        &lt;div&gt;\n          &lt;button type=\"submit\" className='mt-2 bg-red-400 hover:bg-red-600 text-white p-3 rounded mr-2 disabled:pointer-events-none' \n            disabled={mutation.isLoading}&gt;\n            Add&lt;/button&gt;\n          &lt;button className='mt-2 bg-gray-700 hover:bg-gray-600 text-white p-3 rounded'\n            onClick={closeForm}&gt;Cancel&lt;/button&gt;\n        &lt;/div&gt;\n      &lt;/form&gt;\n    &lt;/div&gt;\n  )\n}</code></pre><p>Here's a brief explanation of this form</p><ol><li>This form acts as a pop-up. It accepts <code>isOpen</code> and <code>setIsOpen</code> props to determine when the form is opened and handle closing it.</li><li>You use <code>useQueryClient</code> to get access to the Query Client. This is necessary to perform a mutation.</li><li>To handle adding a note on your server and keep all data in your query client synced, you must the <code>useMutation</code> hook. </li><li>The <code>useMutation</code> hook accepts 2 parameters. Thie first one is the function that will handle the mutation, which in this case is <code>insertNote</code>. The second parameter is an object of <a href=\"https://tanstack.com/query/v4/docs/reference/useMutation\">options</a>. You pass it one option <code>onSuccess</code> which is a function that runs if the mutation is performed successfully. You use this to reset the <code>title</code> and <code>content</code> fields of the form.</li><li>In <code>insertNote</code>, you send a <code>POST</code> request to <code>localhost:3001/notes</code> and pass in the body the <code>title</code> and <code>content</code> of the note to be created. If the <code>success</code> body parameter returned from the server is <code>false</code>, an error is thrown to signal that the mutation failed. </li><li>If the note is added successfully, you change the cached value of the <code>notes</code> key using the <code>queryClient.setQueriesData</code> method. This method accepts the key as a first parameter and the new data associated with that key as a second parameter. This updates the data everywhere it's used on your website.</li><li>In this component you display a form with 2 fields: <code>title</code> and <code>content</code>. In the form, you check if an error occurs using <code>mutation.isError</code> and get access to the error using <code>mutation.error</code>.</li><li>You handle form submission in the <code>handleSubmit</code> function. Here, you trigger the mutation using <code>mutation.mutate</code>. This is where the <code>insertNote</code> function is triggered to add a new note.</li></ol><p>Then, in <code>src/app.js</code> add the following imports at the beginning of the file:</p><pre><code class=\"language-js\">import Form from './form'\nimport { useState } from 'react'</code></pre><p>Then, at the beginning of the component add a new state variable to manage wheter the form is opened or not:</p><pre><code class=\"language-js\">const [isOpen, setIsOpen] = useState(false)</code></pre><p>Next, add a new function <code>addNote</code> that just uses <code>setIsOpen</code> to open the form:</p><pre><code class=\"language-js\">function addNote () {\n    setIsOpen(true)\n}</code></pre><p>Finally, in the returned JSX, replace the button with the plus icon with the following:</p><pre><code class=\"language-js\">&lt;button className=\"mt-2 bg-gray-700 hover:bg-gray-600 rounded-full text-white p-3\" onClick={addNote}&gt;\n    &lt;PlusIcon className='w-5 h-5'&gt;&lt;/PlusIcon&gt;\n&lt;/button&gt;\n&lt;Form isOpen={isOpen} setIsOpen={setIsOpen} /&gt;</code></pre><p>This sets the <code>onClick</code> handler of the button to <code>addNote</code>. It also adds the <code>Form</code> component you created earlier as a child component of <code>App</code>. </p><h3 id=\"test-adding-a-note\">Test Adding a Note</h3><p>Rerun your server and React app if they're not running. Then, open the website again at <code>localhost:3000</code>. Click on the plus button and a pop up will open with the form to add a new note.</p><figure class=\"kg-card kg-image-card\"><img src=\"https://backend.shahednasser.com/content/images/2022/07/Screen-Shot-2022-07-24-at-6.31.41-PM.png\" class=\"kg-image\" alt loading=\"lazy\" width=\"1494\" height=\"792\" srcset=\"https://backend.shahednasser.com/content/images/size/w600/2022/07/Screen-Shot-2022-07-24-at-6.31.41-PM.png 600w, https://backend.shahednasser.com/content/images/size/w1000/2022/07/Screen-Shot-2022-07-24-at-6.31.41-PM.png 1000w, https://backend.shahednasser.com/content/images/2022/07/Screen-Shot-2022-07-24-at-6.31.41-PM.png 1494w\" sizes=\"(min-width: 720px) 720px\"></figure><p>Enter a random title and content then click Add. The pop up form will then close and you can see the new note added.</p><figure class=\"kg-card kg-image-card\"><img src=\"https://backend.shahednasser.com/content/images/2022/07/Screen-Shot-2022-07-24-at-6.32.53-PM.png\" class=\"kg-image\" alt loading=\"lazy\" width=\"1418\" height=\"720\" srcset=\"https://backend.shahednasser.com/content/images/size/w600/2022/07/Screen-Shot-2022-07-24-at-6.32.53-PM.png 600w, https://backend.shahednasser.com/content/images/size/w1000/2022/07/Screen-Shot-2022-07-24-at-6.32.53-PM.png 1000w, https://backend.shahednasser.com/content/images/2022/07/Screen-Shot-2022-07-24-at-6.32.53-PM.png 1418w\" sizes=\"(min-width: 720px) 720px\"></figure><h3 id=\"implement-delete-note-functionality\">Implement Delete Note Functionality</h3><p>The last functionality you'll add is deleting notes. Deleting a note is another act of mutation as it manipulates the server's data.</p><p>At the beginning of the <code>App</code> component in <code>src/app.js</code> add the following code:</p><pre><code class=\"language-js\">const queryClient = useQueryClient()\nconst mutation = useMutation(deleteNote, {\n    onSuccess: () =&gt; queryClient.invalidateQueries('notes')\n})</code></pre><p>Here, you get access to the query client using <code>useQueryClient</code>. Then, you create a new mutation using <code>useMutation</code>. You pass it the function <code>deleteNote</code> (which you'll create next) as a first parameter and an object of options. </p><p>To the <code>onSuccess</code> option you pass a function that does one thing. It executes the method <code>queryClient.invalidateQueries</code>. This method marks the cached data for a specific key as outdated, which triggers retrieving the data again. </p><p>So, once a note is deleted, the query you created earlier that executes the function <code>fetchNotes</code> will be triggered and the notes will be fetched again. If you had created other queries on your website that use the same key <code>notes</code>, they'll also be triggered to update their data. </p><p>Next, add the function <code>deleteNote</code> in the <code>App</code> component in the same file:</p><pre><code class=\"language-js\">function deleteNote (note) {\n    return fetch(`http://localhost:3001/notes/${note.id}`, {\n      method: 'DELETE'\n    })\n    .then((response) =&gt; response.json())\n    .then(({ success, message }) =&gt; {\n      if (!success) {\n        throw new Error(message);\n      }\n\n      alert(message);\n    })\n  }</code></pre><p>This function receives the <code>note</code> to be deleted as a parameter. It sends a <code>DELETE</code> request to <code>localhost:3001/notes/:id</code>. If the <code>success</code> body parameter of the response is <code>false</code>, an error is thrown. Otherwise, only an alert is shown.</p><p>Then, in the returned JSX of the <code>App</code> component, change how the loading icon and error where shown previously to the following:</p><pre><code class=\"language-js\">{(isLoading || mutation.isLoading) &amp;&amp; &lt;RefreshIcon className=\"w-10 h-10 animate-spin mx-auto\"&gt;&lt;/RefreshIcon&gt;}\n{(isError || mutation.isError) &amp;&amp; &lt;span className='text-red'&gt;{error ? (error.message ? error.message : error) : mutation.error.message}&lt;/span&gt;}</code></pre><p>This shows the loading icon or the error message for both the query that fetches the notes and the mutation that handles deleting a note.</p><p>Finally, find the delete button of a note and add an <code>onClick</code> handler:</p><pre><code class=\"language-js\">&lt;button className='link text-gray-400' onClick={() =&gt; mutation.mutate(note)}&gt;Delete&lt;/button&gt;</code></pre><p>On click, the mutation responsible for deleting the note is triggered using <code>mutation.mutate</code>. You pass it the note to delete which is the current note in a <code>map</code> loop.</p><h3 id=\"test-deleting-a-note\">Test Deleting a Note</h3><p>Rerun your server and React app if they're not running. Then, open the website again at <code>localhost:3000</code>. Click the Delete link for any of your notes. If the note is deleted successfully, an alert will be shown.</p><figure class=\"kg-card kg-image-card\"><img src=\"https://backend.shahednasser.com/content/images/2022/07/Screen-Shot-2022-07-01-at-2.48.53-PM.png\" class=\"kg-image\" alt loading=\"lazy\" width=\"1006\" height=\"314\" srcset=\"https://backend.shahednasser.com/content/images/size/w600/2022/07/Screen-Shot-2022-07-01-at-2.48.53-PM.png 600w, https://backend.shahednasser.com/content/images/size/w1000/2022/07/Screen-Shot-2022-07-01-at-2.48.53-PM.png 1000w, https://backend.shahednasser.com/content/images/2022/07/Screen-Shot-2022-07-01-at-2.48.53-PM.png 1006w\" sizes=\"(min-width: 720px) 720px\"></figure><p>After closing the alert, the notes will be fetched again and displayed, if there are any other notes.</p><figure class=\"kg-card kg-image-card\"><img src=\"https://backend.shahednasser.com/content/images/2022/07/Screen-Shot-2022-06-28-at-9.10.04-PM-1.png\" class=\"kg-image\" alt loading=\"lazy\" width=\"1446\" height=\"490\" srcset=\"https://backend.shahednasser.com/content/images/size/w600/2022/07/Screen-Shot-2022-06-28-at-9.10.04-PM-1.png 600w, https://backend.shahednasser.com/content/images/size/w1000/2022/07/Screen-Shot-2022-06-28-at-9.10.04-PM-1.png 1000w, https://backend.shahednasser.com/content/images/2022/07/Screen-Shot-2022-06-28-at-9.10.04-PM-1.png 1446w\" sizes=\"(min-width: 720px) 720px\"></figure><h2 id=\"conclusion\">Conclusion</h2><p>Using React (TanStack) Query, you can easily handle server data fetching and manipulation on your website with advanced features such as caching and synchronization across your React app.</p><p>Make sure to check out the <a href=\"https://tanstack.com/query/v4\">official documentation</a> to learn more about what you can do with React Query.</p>","url":"https://backend.shahednasser.com/react-query-tutorial-for-beginners/","canonical_url":null,"uuid":"59ed8cc6-4d4d-4eac-a4c7-5bfd0118df23","codeinjection_foot":null,"codeinjection_head":null,"codeinjection_styles":null,"comment_id":"62dd14674e918d05f353777d","reading_time":13,"send_email_when_published":null,"email_subject":null,"childHtmlRehype":{"html":"<p>React Query (now rebranded to TanStack Query) is a React library used to make fetching and manipulating server-side data easier. Using React Query, you can implement, along with data fetching, caching, and synchronization of your data with the server.</p><p>In this tutorial, you'll build a simple Node.js server and then learn how to interact with it on a React website using React Query.</p><p>Please note that this version uses v4 of React Query which is now named TanStack Query.</p><p>You can find the code for this tutorial in <a href=\"https://github.com/shahednasser/react-query-tutorial\">this GitHub repository</a>.</p><h2 id=\"prerequisites\">Prerequisites</h2><p> Before starting with this tutorial make sure you have <a href=\"https://nodejs.org/en/\">Node.js installed</a>. You need at least version 14.</p><h2 id=\"server-setup\">Server Setup</h2><p>In this section, you'll set up a simple Node.js server with an SQLite database. The server has 3 endpoints to fetch, add, and delete notes.</p><p>If you already have a server you can skip this section and go to the Website Setup section.</p><h3 id=\"create-server-project\">Create Server Project</h3><p>Create a new directory called <code class=\"language-text\">server</code> then initialize a new project using NPM:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\"><span class=\"token function\">mkdir</span> server\n<span class=\"token builtin class-name\">cd</span> server\n<span class=\"token function\">npm</span> init -y</code></pre></div><h3 id=\"install-dependencies\">Install Dependencies</h3><p>Then, install the packages you'll need for the development of the server:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\"><span class=\"token function\">npm</span> i express cors body-parser sqlite3 nodemon</code></pre></div><p>Here's what each of the packages is for:</p><ol><li><code class=\"language-text\">express</code> to create a server using <a href=\"https://expressjs.com/\">Express</a>.</li><li><code class=\"language-text\">cors</code> is an Express middleware used to handle <a href=\"https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS\">CORS</a> on your server.</li><li><code class=\"language-text\">body-parser</code> is an Express middleware used to parse the body of a request.</li><li><code class=\"language-text\">sqlite3</code> is an SQLite database adapter for Node.js.</li><li><code class=\"language-text\">nodemon</code> is a library used to restart the server whenever new changes occur to the files.</li></ol><h3 id=\"create-server\">Create Server</h3><p>Create the file <code class=\"language-text\">index.js</code> with the following content:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">const</span> express <span class=\"token operator\">=</span> <span class=\"token function\">require</span><span class=\"token punctuation\">(</span><span class=\"token string\">'express'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token keyword\">const</span> app <span class=\"token operator\">=</span> <span class=\"token function\">express</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">const</span> port <span class=\"token operator\">=</span> <span class=\"token number\">3001</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">const</span> cors <span class=\"token operator\">=</span> <span class=\"token function\">require</span><span class=\"token punctuation\">(</span><span class=\"token string\">'cors'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">const</span> sqlite3 <span class=\"token operator\">=</span> <span class=\"token function\">require</span><span class=\"token punctuation\">(</span><span class=\"token string\">'sqlite3'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">verbose</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">const</span> bodyParser <span class=\"token operator\">=</span> <span class=\"token function\">require</span><span class=\"token punctuation\">(</span><span class=\"token string\">'body-parser'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\napp<span class=\"token punctuation\">.</span><span class=\"token function\">use</span><span class=\"token punctuation\">(</span>bodyParser<span class=\"token punctuation\">.</span><span class=\"token function\">json</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\napp<span class=\"token punctuation\">.</span><span class=\"token function\">use</span><span class=\"token punctuation\">(</span><span class=\"token function\">cors</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\napp<span class=\"token punctuation\">.</span><span class=\"token function\">listen</span><span class=\"token punctuation\">(</span>port<span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  console<span class=\"token punctuation\">.</span><span class=\"token function\">log</span><span class=\"token punctuation\">(</span><span class=\"token template-string\"><span class=\"token template-punctuation string\">`</span><span class=\"token string\">Notes app listening on port </span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${</span>port<span class=\"token interpolation-punctuation punctuation\">}</span></span><span class=\"token template-punctuation string\">`</span></span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div><p>This initializes the server using Express on port <code class=\"language-text\">3001</code>. It also uses the <code class=\"language-text\">cors</code> and <code class=\"language-text\">body-parser</code> middleware.</p><p>Then, in <code class=\"language-text\">package.json</code> add a new script <code class=\"language-text\">start</code> to run the server:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"json\"><pre class=\"language-json\"><code class=\"language-json\">  <span class=\"token property\">\"scripts\"</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token property\">\"start\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"nodemon index.js\"</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span></code></pre></div><h3 id=\"initialize-the-database\">Initialize the Database</h3><p>In <code class=\"language-text\">index.js</code> before <code class=\"language-text\">app.listen</code> add the following code:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">const</span> db <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">sqlite3<span class=\"token punctuation\">.</span>Database</span><span class=\"token punctuation\">(</span><span class=\"token string\">'data.db'</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">err</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>err<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">throw</span> err<span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n\n  <span class=\"token comment\">// create tables if they don't exist</span>\n  db<span class=\"token punctuation\">.</span><span class=\"token function\">serialize</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    db<span class=\"token punctuation\">.</span><span class=\"token function\">run</span><span class=\"token punctuation\">(</span><span class=\"token template-string\"><span class=\"token template-punctuation string\">`</span><span class=\"token string\">CREATE TABLE IF NOT EXISTS notes (id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT, content TEXT, \n      created_at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP)</span><span class=\"token template-punctuation string\">`</span></span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div><p>This creates a new database if it doesn't exist in the file <code class=\"language-text\">data.db</code>. Then, if the <code class=\"language-text\">notes</code> table doesn't exist on the database it creates it as well.</p><h3 id=\"add-endpoints\">Add Endpoints</h3><p>Following the database code, add the following code to add the endpoints:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\">app<span class=\"token punctuation\">.</span><span class=\"token function\">get</span><span class=\"token punctuation\">(</span><span class=\"token string\">'/notes'</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">req<span class=\"token punctuation\">,</span> res</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  db<span class=\"token punctuation\">.</span><span class=\"token function\">all</span><span class=\"token punctuation\">(</span><span class=\"token string\">'SELECT * FROM notes'</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">err<span class=\"token punctuation\">,</span> rows</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>err<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n      console<span class=\"token punctuation\">.</span><span class=\"token function\">error</span><span class=\"token punctuation\">(</span>err<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n      <span class=\"token keyword\">return</span> res<span class=\"token punctuation\">.</span><span class=\"token function\">status</span><span class=\"token punctuation\">(</span><span class=\"token number\">500</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">json</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">success</span><span class=\"token operator\">:</span> <span class=\"token boolean\">false</span><span class=\"token punctuation\">,</span> <span class=\"token literal-property property\">message</span><span class=\"token operator\">:</span> <span class=\"token string\">'An error occurred, please try again later'</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token keyword\">return</span> res<span class=\"token punctuation\">.</span><span class=\"token function\">json</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">success</span><span class=\"token operator\">:</span> <span class=\"token boolean\">true</span><span class=\"token punctuation\">,</span> <span class=\"token literal-property property\">data</span><span class=\"token operator\">:</span> rows <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\napp<span class=\"token punctuation\">.</span><span class=\"token function\">get</span><span class=\"token punctuation\">(</span><span class=\"token string\">'/notes/:id'</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">req<span class=\"token punctuation\">,</span> res</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  db<span class=\"token punctuation\">.</span><span class=\"token function\">get</span><span class=\"token punctuation\">(</span><span class=\"token string\">'SELECT * FROM notes WHERE id = ?'</span><span class=\"token punctuation\">,</span> req<span class=\"token punctuation\">.</span>params<span class=\"token punctuation\">.</span>id<span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">err<span class=\"token punctuation\">,</span> row</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>err<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n      console<span class=\"token punctuation\">.</span><span class=\"token function\">error</span><span class=\"token punctuation\">(</span>err<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n      <span class=\"token keyword\">return</span> res<span class=\"token punctuation\">.</span><span class=\"token function\">status</span><span class=\"token punctuation\">(</span><span class=\"token number\">500</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">json</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">success</span><span class=\"token operator\">:</span> <span class=\"token boolean\">false</span><span class=\"token punctuation\">,</span> <span class=\"token literal-property property\">message</span><span class=\"token operator\">:</span> <span class=\"token string\">'An error occurred, please try again later'</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">!</span>row<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n      <span class=\"token keyword\">return</span> res<span class=\"token punctuation\">.</span><span class=\"token function\">status</span><span class=\"token punctuation\">(</span><span class=\"token number\">404</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">json</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">success</span><span class=\"token operator\">:</span> <span class=\"token boolean\">false</span><span class=\"token punctuation\">,</span> <span class=\"token literal-property property\">message</span><span class=\"token operator\">:</span> <span class=\"token string\">'Note does not exist'</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token keyword\">return</span> res<span class=\"token punctuation\">.</span><span class=\"token function\">json</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">success</span><span class=\"token operator\">:</span> <span class=\"token boolean\">true</span><span class=\"token punctuation\">,</span> <span class=\"token literal-property property\">data</span><span class=\"token operator\">:</span> row <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\napp<span class=\"token punctuation\">.</span><span class=\"token function\">post</span><span class=\"token punctuation\">(</span><span class=\"token string\">'/notes'</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">req<span class=\"token punctuation\">,</span> res</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">const</span> <span class=\"token punctuation\">{</span> title<span class=\"token punctuation\">,</span> content <span class=\"token punctuation\">}</span> <span class=\"token operator\">=</span> req<span class=\"token punctuation\">.</span>body<span class=\"token punctuation\">;</span>\n\n  <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">!</span>title <span class=\"token operator\">||</span> <span class=\"token operator\">!</span>content<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">return</span> res<span class=\"token punctuation\">.</span><span class=\"token function\">status</span><span class=\"token punctuation\">(</span><span class=\"token number\">400</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">json</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">success</span><span class=\"token operator\">:</span> <span class=\"token boolean\">false</span><span class=\"token punctuation\">,</span> <span class=\"token literal-property property\">message</span><span class=\"token operator\">:</span> <span class=\"token string\">'title and content are required'</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n\n  db<span class=\"token punctuation\">.</span><span class=\"token function\">run</span><span class=\"token punctuation\">(</span><span class=\"token string\">'INSERT INTO notes (title, content) VALUES (?, ?)'</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">[</span>title<span class=\"token punctuation\">,</span> content<span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> <span class=\"token keyword\">function</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">err</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>err<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n      console<span class=\"token punctuation\">.</span><span class=\"token function\">error</span><span class=\"token punctuation\">(</span>err<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n      <span class=\"token keyword\">return</span> res<span class=\"token punctuation\">.</span><span class=\"token function\">status</span><span class=\"token punctuation\">(</span><span class=\"token number\">500</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">json</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">success</span><span class=\"token operator\">:</span> <span class=\"token boolean\">false</span><span class=\"token punctuation\">,</span> <span class=\"token literal-property property\">message</span><span class=\"token operator\">:</span> <span class=\"token string\">'An error occurred, please try again later'</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token keyword\">return</span> res<span class=\"token punctuation\">.</span><span class=\"token function\">json</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>\n      <span class=\"token literal-property property\">success</span><span class=\"token operator\">:</span> <span class=\"token boolean\">true</span><span class=\"token punctuation\">,</span>\n      <span class=\"token literal-property property\">data</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token literal-property property\">id</span><span class=\"token operator\">:</span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>lastID<span class=\"token punctuation\">,</span>\n        title<span class=\"token punctuation\">,</span>\n        content<span class=\"token punctuation\">,</span>\n      <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\napp<span class=\"token punctuation\">.</span><span class=\"token function\">delete</span><span class=\"token punctuation\">(</span><span class=\"token string\">'/notes/:id'</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">req<span class=\"token punctuation\">,</span> res</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">const</span> <span class=\"token punctuation\">{</span> id <span class=\"token punctuation\">}</span> <span class=\"token operator\">=</span> req<span class=\"token punctuation\">.</span>params<span class=\"token punctuation\">;</span>\n\n  db<span class=\"token punctuation\">.</span><span class=\"token function\">get</span><span class=\"token punctuation\">(</span><span class=\"token string\">'SELECT * FROM notes WHERE id = ?'</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">[</span>id<span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">err<span class=\"token punctuation\">,</span> row</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>err<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n      console<span class=\"token punctuation\">.</span><span class=\"token function\">error</span><span class=\"token punctuation\">(</span>err<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n      <span class=\"token keyword\">return</span> res<span class=\"token punctuation\">.</span><span class=\"token function\">status</span><span class=\"token punctuation\">(</span><span class=\"token number\">500</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">json</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">success</span><span class=\"token operator\">:</span> <span class=\"token boolean\">false</span><span class=\"token punctuation\">,</span> <span class=\"token literal-property property\">message</span><span class=\"token operator\">:</span> <span class=\"token string\">'An error occurred, please try again later'</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">!</span>row<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n      <span class=\"token keyword\">return</span> res<span class=\"token punctuation\">.</span><span class=\"token function\">status</span><span class=\"token punctuation\">(</span><span class=\"token number\">404</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">json</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">success</span><span class=\"token operator\">:</span> <span class=\"token boolean\">false</span><span class=\"token punctuation\">,</span> <span class=\"token literal-property property\">message</span><span class=\"token operator\">:</span> <span class=\"token string\">'Note does not exist'</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n\n    db<span class=\"token punctuation\">.</span><span class=\"token function\">run</span><span class=\"token punctuation\">(</span><span class=\"token string\">'DELETE FROM notes WHERE id = ?'</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">[</span>id<span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">error</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n      <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>error<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        console<span class=\"token punctuation\">.</span><span class=\"token function\">error</span><span class=\"token punctuation\">(</span>error<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token keyword\">return</span> res<span class=\"token punctuation\">.</span><span class=\"token function\">status</span><span class=\"token punctuation\">(</span><span class=\"token number\">500</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">json</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">success</span><span class=\"token operator\">:</span> <span class=\"token boolean\">false</span><span class=\"token punctuation\">,</span> <span class=\"token literal-property property\">message</span><span class=\"token operator\">:</span> <span class=\"token string\">'An error occurred, please try again later'</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n      <span class=\"token punctuation\">}</span>\n\n      <span class=\"token keyword\">return</span> res<span class=\"token punctuation\">.</span><span class=\"token function\">json</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">success</span><span class=\"token operator\">:</span> <span class=\"token boolean\">true</span><span class=\"token punctuation\">,</span> <span class=\"token literal-property property\">message</span><span class=\"token operator\">:</span> <span class=\"token string\">'Note deleted successfully'</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div><p>Briefly, this creates 4 endpoints:</p><ol><li><code class=\"language-text\">/notes</code> endpoint of the method <code class=\"language-text\">GET</code> to fetch all notes.</li><li><code class=\"language-text\">/notes/:id</code> endpoint of the method <code class=\"language-text\">GET</code> to fetch a note by an ID.</li><li><code class=\"language-text\">/notes</code> endpoint of the method <code class=\"language-text\">POST</code> to add a note.</li><li><code class=\"language-text\">/notes/:id</code> endpoint of the method <code class=\"language-text\">DELETE</code> to delete a note.</li></ol><h3 id=\"test-server\">Test Server</h3><p>Run the following command to start the server:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\"><span class=\"token function\">npm</span> start</code></pre></div><p>This starts the server on port <code class=\"language-text\">3001</code>. You can test it out by sending a request to <code class=\"language-text\">localhost:3001/notes</code>.</p><h2 id=\"website-setup\">Website Setup</h2><p>In this section, you'll create the website with Create React App (CRA). This is where you'll make use of React Query.</p><h3 id=\"create-website-project\">Create Website Project</h3><p>To create a new React app, run the following command in a different directory:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">npx create-react-app website</code></pre></div><p>This creates a new React app in the directory <code class=\"language-text\">website</code>.</p><h3 id=\"install-dependencies-1\">Install Dependencies</h3><p>Run the following command to change to the <code class=\"language-text\">website</code> directory and install the necessary dependencies for the website:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\"><span class=\"token builtin class-name\">cd</span> website\n<span class=\"token function\">npm</span> i @tanstack/react-query tailwindcss postcss autoprefixer @tailwindcss/typography @heroicons/react @windmill/react-ui</code></pre></div><p>The <code class=\"language-text\">@tanstack/react-query</code> library is the React Query library which is now named TanStack Query. The other libraries are <a href=\"https://tailwindcss.com/\">Tailwind CSS</a> related libraries to add styling to the website.</p><h3 id=\"tailwind-css-setup\">Tailwind CSS Setup</h3><p>This section is optional and is only used to set up Tailwind CSS.</p><p>Create the file <code class=\"language-text\">postcss.config.js</code> with the following content:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\">module<span class=\"token punctuation\">.</span>exports <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token literal-property property\">plugins</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token literal-property property\">tailwindcss</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span><span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n    <span class=\"token literal-property property\">autoprefixer</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span><span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n<span class=\"token punctuation\">}</span>\n</code></pre></div><p>Also, create the file <code class=\"language-text\">tailwind.config.js</code> with the following content:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token comment\">/** @type {import('tailwindcss').Config} */</span>\nmodule<span class=\"token punctuation\">.</span>exports <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token literal-property property\">content</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">[</span>\n    <span class=\"token string\">\"./src/**/*.{js,jsx,ts,tsx}\"</span><span class=\"token punctuation\">,</span>\n  <span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span>\n  <span class=\"token literal-property property\">theme</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token literal-property property\">extend</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span><span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n  <span class=\"token literal-property property\">plugins</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">[</span>\n    <span class=\"token function\">require</span><span class=\"token punctuation\">(</span><span class=\"token string\">'@tailwindcss/typography'</span><span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span>\n<span class=\"token punctuation\">}</span>\n</code></pre></div><p>Then, create the file <code class=\"language-text\">src/index.css</code> with the following content:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"css\"><pre class=\"language-css\"><code class=\"language-css\"><span class=\"token atrule\"><span class=\"token rule\">@tailwind</span> base<span class=\"token punctuation\">;</span></span>\n<span class=\"token atrule\"><span class=\"token rule\">@tailwind</span> components<span class=\"token punctuation\">;</span></span>\n<span class=\"token atrule\"><span class=\"token rule\">@tailwind</span> utilities<span class=\"token punctuation\">;</span></span></code></pre></div><p>Finally, in <code class=\"language-text\">index.js</code> import <code class=\"language-text\">src/index.css</code> at the beginning of the file:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">import</span> <span class=\"token string\">'./index.css'</span><span class=\"token punctuation\">;</span></code></pre></div><h3 id=\"use-queryclientprovider\">Use QueryClientProvider</h3><p>To use the React Query client in all of your components, you must use it at a high level in your website's components hierarchy. The best place to put it is in <code class=\"language-text\">src/index.js</code> which wraps up your entire website's components.</p><p>In <code class=\"language-text\">src/index.js</code> add the following imports at the beginning of the file:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span>\n  QueryClient<span class=\"token punctuation\">,</span>\n  QueryClientProvider<span class=\"token punctuation\">,</span>\n<span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'@tanstack/react-query'</span></code></pre></div><p>Then, initialize a new Query client:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">const</span> queryClient <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">QueryClient</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></code></pre></div><p>Finally, change the parameter passed to <code class=\"language-text\">root.render</code>:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\">root<span class=\"token punctuation\">.</span><span class=\"token function\">render</span><span class=\"token punctuation\">(</span>\n  <span class=\"token operator\">&#x3C;</span>QueryClientProvider client<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span>queryClient<span class=\"token punctuation\">}</span><span class=\"token operator\">></span>\n    <span class=\"token operator\">&#x3C;</span>App <span class=\"token operator\">/</span><span class=\"token operator\">></span>\n  <span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>QueryClientProvider<span class=\"token operator\">></span>\n<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div><p>This wraps the <code class=\"language-text\">App</code> component which holds the rest of the website's components with <code class=\"language-text\">QueryClientProvider</code>. This provider accepts the prop <code class=\"language-text\">client</code> which is an instance of <code class=\"language-text\">QueryClient</code>.</p><p>Now, all components within the website will have access to the Query Client which is used to fetch, cache, and manipulate the server data.</p><h3 id=\"implement-display-notes\">Implement Display Notes</h3><p>Fetching data from the server is an act of performing a query. Therefore, you'll use <code class=\"language-text\">useQuery</code> in this section.</p><p>You'll display notes in the <code class=\"language-text\">App</code> component. These notes are fetched from the server using the <code class=\"language-text\">/notes</code> endpoint.</p><p>Replace the content of <code class=\"language-text\">app.js</code> with the following content:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span> PlusIcon<span class=\"token punctuation\">,</span> RefreshIcon <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'@heroicons/react/solid'</span>\n<span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span> useMutation<span class=\"token punctuation\">,</span> useQuery<span class=\"token punctuation\">,</span> useQueryClient <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'@tanstack/react-query'</span>\n\n<span class=\"token keyword\">function</span> <span class=\"token function\">App</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">const</span> <span class=\"token punctuation\">{</span> isLoading<span class=\"token punctuation\">,</span> isError<span class=\"token punctuation\">,</span> data<span class=\"token punctuation\">,</span> error <span class=\"token punctuation\">}</span> <span class=\"token operator\">=</span> <span class=\"token function\">useQuery</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">[</span><span class=\"token string\">'notes'</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> fetchNotes<span class=\"token punctuation\">)</span>\n\n  <span class=\"token keyword\">function</span> <span class=\"token function\">fetchNotes</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">return</span> <span class=\"token function\">fetch</span><span class=\"token punctuation\">(</span><span class=\"token string\">'http://localhost:3001/notes'</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">.</span><span class=\"token function\">then</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">response</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> response<span class=\"token punctuation\">.</span><span class=\"token function\">json</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">.</span><span class=\"token function\">then</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token parameter\"><span class=\"token punctuation\">{</span> success<span class=\"token punctuation\">,</span> data <span class=\"token punctuation\">}</span></span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n      <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">!</span>success<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">throw</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Error</span> <span class=\"token punctuation\">(</span><span class=\"token string\">'An error occurred while fetching notes'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n      <span class=\"token punctuation\">}</span>\n      <span class=\"token keyword\">return</span> data<span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">}</span>\n\n  <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span>\n    <span class=\"token operator\">&#x3C;</span>div className<span class=\"token operator\">=</span><span class=\"token string\">\"w-screen h-screen overflow-x-hidden bg-red-400 flex flex-col justify-center items-center\"</span><span class=\"token operator\">></span>\n      <span class=\"token operator\">&#x3C;</span>div className<span class=\"token operator\">=</span><span class=\"token string\">'bg-white w-full md:w-1/2 p-5 text-center rounded shadow-md text-gray-800 prose'</span><span class=\"token operator\">></span>\n        <span class=\"token operator\">&#x3C;</span>h1<span class=\"token operator\">></span>Notes<span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>h1<span class=\"token operator\">></span>\n        <span class=\"token punctuation\">{</span>isLoading <span class=\"token operator\">&#x26;&#x26;</span> <span class=\"token operator\">&#x3C;</span>RefreshIcon className<span class=\"token operator\">=</span><span class=\"token string\">\"w-10 h-10 animate-spin mx-auto\"</span><span class=\"token operator\">></span><span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>RefreshIcon<span class=\"token operator\">></span><span class=\"token punctuation\">}</span>\n        <span class=\"token punctuation\">{</span>isError <span class=\"token operator\">&#x26;&#x26;</span> <span class=\"token operator\">&#x3C;</span>span className<span class=\"token operator\">=</span><span class=\"token string\">'text-red'</span><span class=\"token operator\">></span><span class=\"token punctuation\">{</span>error<span class=\"token punctuation\">.</span>message <span class=\"token operator\">?</span> error<span class=\"token punctuation\">.</span>message <span class=\"token operator\">:</span> error<span class=\"token punctuation\">}</span><span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>span<span class=\"token operator\">></span><span class=\"token punctuation\">}</span>\n        <span class=\"token punctuation\">{</span><span class=\"token operator\">!</span>isLoading <span class=\"token operator\">&#x26;&#x26;</span> <span class=\"token operator\">!</span>isError <span class=\"token operator\">&#x26;&#x26;</span> data <span class=\"token operator\">&#x26;&#x26;</span> <span class=\"token operator\">!</span>data<span class=\"token punctuation\">.</span>length <span class=\"token operator\">&#x26;&#x26;</span> <span class=\"token operator\">&#x3C;</span>span className<span class=\"token operator\">=</span><span class=\"token string\">'text-red-400'</span><span class=\"token operator\">></span>You have no notes<span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>span<span class=\"token operator\">></span><span class=\"token punctuation\">}</span>\n        <span class=\"token punctuation\">{</span>data <span class=\"token operator\">&#x26;&#x26;</span> data<span class=\"token punctuation\">.</span>length <span class=\"token operator\">></span> <span class=\"token number\">0</span> <span class=\"token operator\">&#x26;&#x26;</span> data<span class=\"token punctuation\">.</span><span class=\"token function\">map</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">note<span class=\"token punctuation\">,</span> index</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">(</span>\n          <span class=\"token operator\">&#x3C;</span>div key<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span>note<span class=\"token punctuation\">.</span>id<span class=\"token punctuation\">}</span> className<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span><span class=\"token template-string\"><span class=\"token template-punctuation string\">`</span><span class=\"token string\">text-left </span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${</span>index <span class=\"token operator\">!==</span> data<span class=\"token punctuation\">.</span>length <span class=\"token operator\">-</span> <span class=\"token number\">1</span> <span class=\"token operator\">?</span> <span class=\"token string\">'border-b pb-2'</span> <span class=\"token operator\">:</span> <span class=\"token string\">''</span><span class=\"token interpolation-punctuation punctuation\">}</span></span><span class=\"token template-punctuation string\">`</span></span><span class=\"token punctuation\">}</span><span class=\"token operator\">></span>\n            <span class=\"token operator\">&#x3C;</span>h2<span class=\"token operator\">></span><span class=\"token punctuation\">{</span>note<span class=\"token punctuation\">.</span>title<span class=\"token punctuation\">}</span><span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>h2<span class=\"token operator\">></span>\n            <span class=\"token operator\">&#x3C;</span>p<span class=\"token operator\">></span><span class=\"token punctuation\">{</span>note<span class=\"token punctuation\">.</span>content<span class=\"token punctuation\">}</span><span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>p<span class=\"token operator\">></span>\n            <span class=\"token operator\">&#x3C;</span>span<span class=\"token operator\">></span>\n              <span class=\"token operator\">&#x3C;</span>button className<span class=\"token operator\">=</span><span class=\"token string\">'link text-gray-400'</span><span class=\"token operator\">></span>Delete<span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>button<span class=\"token operator\">></span>\n            <span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>span<span class=\"token operator\">></span>\n          <span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>div<span class=\"token operator\">></span>\n        <span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">}</span>\n      <span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>div<span class=\"token operator\">></span>\n      <span class=\"token operator\">&#x3C;</span>button className<span class=\"token operator\">=</span><span class=\"token string\">\"mt-2 bg-gray-700 hover:bg-gray-600 rounded-full text-white p-3\"</span><span class=\"token operator\">></span>\n        <span class=\"token operator\">&#x3C;</span>PlusIcon className<span class=\"token operator\">=</span><span class=\"token string\">'w-5 h-5'</span><span class=\"token operator\">></span><span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>PlusIcon<span class=\"token operator\">></span>\n      <span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>button<span class=\"token operator\">></span>\n    <span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>div<span class=\"token operator\">></span>\n  <span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">export</span> <span class=\"token keyword\">default</span> App<span class=\"token punctuation\">;</span></code></pre></div><p>Here's briefly what's going on in this code snippet:</p><ol><li>You use <code class=\"language-text\">useQuery</code> to fetch the notes. The first parameter it accepts is a unique key used for caching. The second parameter is the function used to fetch the data. You pass it the <code class=\"language-text\">fetchNotes</code> function.</li><li><code class=\"language-text\">useQuery</code> returns an object that holds <a href=\"https://tanstack.com/query/v4/docs/reference/useQuery\">many variables</a>. Here, you use 4 of them: <code class=\"language-text\">isLoading</code> is a boolean value that determines whether the data is currently being fetched; <code class=\"language-text\">isError</code> is a boolean value that determines if an error occurred. <code class=\"language-text\">data</code> is the data that is fetched from the server; and <code class=\"language-text\">error</code> is the error message if <code class=\"language-text\">isError</code> is true.</li><li>The <code class=\"language-text\">fetchNotes</code> function must return a promise that either resolves data or throws an error. In the function, you send a <code class=\"language-text\">GET</code> request to <code class=\"language-text\">localhost:3001/notes</code> to fetch the notes. If the data is fetched successfully it is returned in the <code class=\"language-text\">then</code> fulfillment function. </li><li>In the returned JSX, if <code class=\"language-text\">isLoading</code> is true, a loading icon is shown. If <code class=\"language-text\">isError</code> is true, an error message is shown. If <code class=\"language-text\">data</code> is fetched successfully and has any data in it, the notes are rendered.</li><li>You also show a button with a plus icon to add new notes. You'll implement this later.</li></ol><h3 id=\"test-displaying-notes\">Test Displaying Notes</h3><p>To test out what you've implemented so far, make sure your server is still running, then start your React app server with the following command:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\"><span class=\"token function\">npm</span> start</code></pre></div><p>This runs your React app on <code class=\"language-text\">localhost:3000</code> by default. If you open it in your browser, you'll see a loading icon at first then you'll see no notes as you haven't added any yet.</p><figure class=\"kg-card kg-image-card\"><img src=\"https://backend.shahednasser.com/content/images/2022/07/Screen-Shot-2022-06-28-at-9.10.04-PM.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"1446\" height=\"490\" srcset=\"https://backend.shahednasser.com/content/images/size/w600/2022/07/Screen-Shot-2022-06-28-at-9.10.04-PM.png 600w, https://backend.shahednasser.com/content/images/size/w1000/2022/07/Screen-Shot-2022-06-28-at-9.10.04-PM.png 1000w, https://backend.shahednasser.com/content/images/2022/07/Screen-Shot-2022-06-28-at-9.10.04-PM.png 1446w\" sizes=\"(min-width: 720px) 720px\"></figure><h3 id=\"implement-add-notes-functionality\">Implement Add Notes Functionality</h3><p>Adding a note is an act of mutation on the server data. Therefore, you'll be using the <code class=\"language-text\">useMutation</code> hook in this section.</p><p>You'll create a separate component that shows the form used to add a note.</p><p>Create the file <code class=\"language-text\">src/form.js</code> with the following content:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span> useMutation<span class=\"token punctuation\">,</span> useQueryClient <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'@tanstack/react-query'</span>\n\n<span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span> useState <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'react'</span>\n\n<span class=\"token keyword\">export</span> <span class=\"token keyword\">default</span> <span class=\"token keyword\">function</span> <span class=\"token function\">Form</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\"><span class=\"token punctuation\">{</span> isOpen<span class=\"token punctuation\">,</span> setIsOpen <span class=\"token punctuation\">}</span></span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">const</span> <span class=\"token punctuation\">[</span>title<span class=\"token punctuation\">,</span> setTitle<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token function\">useState</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"\"</span><span class=\"token punctuation\">)</span>\n  <span class=\"token keyword\">const</span> <span class=\"token punctuation\">[</span>content<span class=\"token punctuation\">,</span> setContent<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token function\">useState</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"\"</span><span class=\"token punctuation\">)</span>\n  <span class=\"token keyword\">const</span> queryClient <span class=\"token operator\">=</span> <span class=\"token function\">useQueryClient</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n\n  <span class=\"token keyword\">const</span> mutation <span class=\"token operator\">=</span> <span class=\"token function\">useMutation</span><span class=\"token punctuation\">(</span>insertNote<span class=\"token punctuation\">,</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token function-variable function\">onSuccess</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n      <span class=\"token function\">setTitle</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"\"</span><span class=\"token punctuation\">)</span>\n      <span class=\"token function\">setContent</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"\"</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n\n  <span class=\"token keyword\">function</span> <span class=\"token function\">closeForm</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">e</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    e<span class=\"token punctuation\">.</span><span class=\"token function\">preventDefault</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    <span class=\"token function\">setIsOpen</span><span class=\"token punctuation\">(</span><span class=\"token boolean\">false</span><span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">}</span>\n\n  <span class=\"token keyword\">function</span> <span class=\"token function\">insertNote</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">return</span> <span class=\"token function\">fetch</span><span class=\"token punctuation\">(</span><span class=\"token template-string\"><span class=\"token template-punctuation string\">`</span><span class=\"token string\">http://localhost:3001/notes</span><span class=\"token template-punctuation string\">`</span></span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">{</span>\n      <span class=\"token literal-property property\">method</span><span class=\"token operator\">:</span> <span class=\"token string\">'POST'</span><span class=\"token punctuation\">,</span>\n      <span class=\"token literal-property property\">headers</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token string-property property\">'Content-Type'</span><span class=\"token operator\">:</span> <span class=\"token string\">'application/json'</span>\n      <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n      <span class=\"token literal-property property\">body</span><span class=\"token operator\">:</span> <span class=\"token constant\">JSON</span><span class=\"token punctuation\">.</span><span class=\"token function\">stringify</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>\n        title<span class=\"token punctuation\">,</span>\n        content\n      <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">.</span><span class=\"token function\">then</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">response</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> response<span class=\"token punctuation\">.</span><span class=\"token function\">json</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">.</span><span class=\"token function\">then</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token parameter\"><span class=\"token punctuation\">{</span> success<span class=\"token punctuation\">,</span> data <span class=\"token punctuation\">}</span></span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n      <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">!</span>success<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">throw</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Error</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"An error occured\"</span><span class=\"token punctuation\">)</span>\n      <span class=\"token punctuation\">}</span>\n      \n      <span class=\"token function\">setIsOpen</span><span class=\"token punctuation\">(</span><span class=\"token boolean\">false</span><span class=\"token punctuation\">)</span>\n      queryClient<span class=\"token punctuation\">.</span><span class=\"token function\">setQueriesData</span><span class=\"token punctuation\">(</span><span class=\"token string\">'notes'</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">old</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">[</span><span class=\"token operator\">...</span>old<span class=\"token punctuation\">,</span> data<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">}</span>\n\n  <span class=\"token keyword\">function</span> <span class=\"token function\">handleSubmit</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">e</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    e<span class=\"token punctuation\">.</span><span class=\"token function\">preventDefault</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    mutation<span class=\"token punctuation\">.</span><span class=\"token function\">mutate</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">}</span>\n\n  <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span>\n    <span class=\"token operator\">&#x3C;</span>div className<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span><span class=\"token template-string\"><span class=\"token template-punctuation string\">`</span><span class=\"token string\">absolute w-full h-full top-0 left-0 z-50 flex justify-center items-center </span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${</span><span class=\"token operator\">!</span>isOpen <span class=\"token operator\">?</span> <span class=\"token string\">'hidden'</span> <span class=\"token operator\">:</span> <span class=\"token string\">''</span><span class=\"token interpolation-punctuation punctuation\">}</span></span><span class=\"token template-punctuation string\">`</span></span><span class=\"token punctuation\">}</span><span class=\"token operator\">></span>\n      <span class=\"token operator\">&#x3C;</span>div className<span class=\"token operator\">=</span><span class=\"token string\">'bg-black opacity-50 absolute w-full h-full top-0 left-0'</span><span class=\"token operator\">></span><span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>div<span class=\"token operator\">></span>\n      <span class=\"token operator\">&#x3C;</span>form className<span class=\"token operator\">=</span><span class=\"token string\">'bg-white w-full md:w-1/2 p-5 rounded shadow-md text-gray-800 prose relative'</span> \n        onSubmit<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span>handleSubmit<span class=\"token punctuation\">}</span><span class=\"token operator\">></span>\n        <span class=\"token operator\">&#x3C;</span>h2 className<span class=\"token operator\">=</span><span class=\"token string\">'text-center'</span><span class=\"token operator\">></span>Add Note<span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>h2<span class=\"token operator\">></span>\n        <span class=\"token punctuation\">{</span>mutation<span class=\"token punctuation\">.</span>isError <span class=\"token operator\">&#x26;&#x26;</span> <span class=\"token operator\">&#x3C;</span>span className<span class=\"token operator\">=</span><span class=\"token string\">'block mb-2 text-red-400'</span><span class=\"token operator\">></span><span class=\"token punctuation\">{</span>mutation<span class=\"token punctuation\">.</span>error<span class=\"token punctuation\">.</span>message <span class=\"token operator\">?</span> mutation<span class=\"token punctuation\">.</span>error<span class=\"token punctuation\">.</span>message <span class=\"token operator\">:</span> mutation<span class=\"token punctuation\">.</span>error<span class=\"token punctuation\">}</span><span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>span<span class=\"token operator\">></span><span class=\"token punctuation\">}</span>\n        <span class=\"token operator\">&#x3C;</span>input type<span class=\"token operator\">=</span><span class=\"token string\">\"text\"</span> placeholder<span class=\"token operator\">=</span><span class=\"token string\">'Title'</span> className<span class=\"token operator\">=</span><span class=\"token string\">'rounded-sm w-full border px-2'</span> \n          value<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span>title<span class=\"token punctuation\">}</span> onChange<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">e</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token function\">setTitle</span><span class=\"token punctuation\">(</span>e<span class=\"token punctuation\">.</span>target<span class=\"token punctuation\">.</span>value<span class=\"token punctuation\">)</span><span class=\"token punctuation\">}</span> <span class=\"token operator\">/</span><span class=\"token operator\">></span>\n        <span class=\"token operator\">&#x3C;</span>textarea onChange<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">e</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token function\">setContent</span><span class=\"token punctuation\">(</span>e<span class=\"token punctuation\">.</span>target<span class=\"token punctuation\">.</span>value<span class=\"token punctuation\">)</span><span class=\"token punctuation\">}</span> \n          className<span class=\"token operator\">=</span><span class=\"token string\">\"rounded-sm w-full border px-2 mt-2\"</span> placeholder<span class=\"token operator\">=</span><span class=\"token string\">'Content'</span> value<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span>content<span class=\"token punctuation\">}</span><span class=\"token operator\">></span><span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>textarea<span class=\"token operator\">></span>\n        <span class=\"token operator\">&#x3C;</span>div<span class=\"token operator\">></span>\n          <span class=\"token operator\">&#x3C;</span>button type<span class=\"token operator\">=</span><span class=\"token string\">\"submit\"</span> className<span class=\"token operator\">=</span><span class=\"token string\">'mt-2 bg-red-400 hover:bg-red-600 text-white p-3 rounded mr-2 disabled:pointer-events-none'</span> \n            disabled<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span>mutation<span class=\"token punctuation\">.</span>isLoading<span class=\"token punctuation\">}</span><span class=\"token operator\">></span>\n            Add<span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>button<span class=\"token operator\">></span>\n          <span class=\"token operator\">&#x3C;</span>button className<span class=\"token operator\">=</span><span class=\"token string\">'mt-2 bg-gray-700 hover:bg-gray-600 text-white p-3 rounded'</span>\n            onClick<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span>closeForm<span class=\"token punctuation\">}</span><span class=\"token operator\">></span>Cancel<span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>button<span class=\"token operator\">></span>\n        <span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>div<span class=\"token operator\">></span>\n      <span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>form<span class=\"token operator\">></span>\n    <span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>div<span class=\"token operator\">></span>\n  <span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span></code></pre></div><p>Here's a brief explanation of this form</p><ol><li>This form acts as a pop-up. It accepts <code class=\"language-text\">isOpen</code> and <code class=\"language-text\">setIsOpen</code> props to determine when the form is opened and handle closing it.</li><li>You use <code class=\"language-text\">useQueryClient</code> to get access to the Query Client. This is necessary to perform a mutation.</li><li>To handle adding a note on your server and keep all data in your query client synced, you must the <code class=\"language-text\">useMutation</code> hook. </li><li>The <code class=\"language-text\">useMutation</code> hook accepts 2 parameters. Thie first one is the function that will handle the mutation, which in this case is <code class=\"language-text\">insertNote</code>. The second parameter is an object of <a href=\"https://tanstack.com/query/v4/docs/reference/useMutation\">options</a>. You pass it one option <code class=\"language-text\">onSuccess</code> which is a function that runs if the mutation is performed successfully. You use this to reset the <code class=\"language-text\">title</code> and <code class=\"language-text\">content</code> fields of the form.</li><li>In <code class=\"language-text\">insertNote</code>, you send a <code class=\"language-text\">POST</code> request to <code class=\"language-text\">localhost:3001/notes</code> and pass in the body the <code class=\"language-text\">title</code> and <code class=\"language-text\">content</code> of the note to be created. If the <code class=\"language-text\">success</code> body parameter returned from the server is <code class=\"language-text\">false</code>, an error is thrown to signal that the mutation failed. </li><li>If the note is added successfully, you change the cached value of the <code class=\"language-text\">notes</code> key using the <code class=\"language-text\">queryClient.setQueriesData</code> method. This method accepts the key as a first parameter and the new data associated with that key as a second parameter. This updates the data everywhere it's used on your website.</li><li>In this component you display a form with 2 fields: <code class=\"language-text\">title</code> and <code class=\"language-text\">content</code>. In the form, you check if an error occurs using <code class=\"language-text\">mutation.isError</code> and get access to the error using <code class=\"language-text\">mutation.error</code>.</li><li>You handle form submission in the <code class=\"language-text\">handleSubmit</code> function. Here, you trigger the mutation using <code class=\"language-text\">mutation.mutate</code>. This is where the <code class=\"language-text\">insertNote</code> function is triggered to add a new note.</li></ol><p>Then, in <code class=\"language-text\">src/app.js</code> add the following imports at the beginning of the file:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">import</span> Form <span class=\"token keyword\">from</span> <span class=\"token string\">'./form'</span>\n<span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span> useState <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'react'</span></code></pre></div><p>Then, at the beginning of the component add a new state variable to manage wheter the form is opened or not:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">const</span> <span class=\"token punctuation\">[</span>isOpen<span class=\"token punctuation\">,</span> setIsOpen<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token function\">useState</span><span class=\"token punctuation\">(</span><span class=\"token boolean\">false</span><span class=\"token punctuation\">)</span></code></pre></div><p>Next, add a new function <code class=\"language-text\">addNote</code> that just uses <code class=\"language-text\">setIsOpen</code> to open the form:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">function</span> <span class=\"token function\">addNote</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token function\">setIsOpen</span><span class=\"token punctuation\">(</span><span class=\"token boolean\">true</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span></code></pre></div><p>Finally, in the returned JSX, replace the button with the plus icon with the following:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token operator\">&#x3C;</span>button className<span class=\"token operator\">=</span><span class=\"token string\">\"mt-2 bg-gray-700 hover:bg-gray-600 rounded-full text-white p-3\"</span> onClick<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span>addNote<span class=\"token punctuation\">}</span><span class=\"token operator\">></span>\n    <span class=\"token operator\">&#x3C;</span>PlusIcon className<span class=\"token operator\">=</span><span class=\"token string\">'w-5 h-5'</span><span class=\"token operator\">></span><span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>PlusIcon<span class=\"token operator\">></span>\n<span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>button<span class=\"token operator\">></span>\n<span class=\"token operator\">&#x3C;</span>Form isOpen<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span>isOpen<span class=\"token punctuation\">}</span> setIsOpen<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span>setIsOpen<span class=\"token punctuation\">}</span> <span class=\"token operator\">/</span><span class=\"token operator\">></span></code></pre></div><p>This sets the <code class=\"language-text\">onClick</code> handler of the button to <code class=\"language-text\">addNote</code>. It also adds the <code class=\"language-text\">Form</code> component you created earlier as a child component of <code class=\"language-text\">App</code>. </p><h3 id=\"test-adding-a-note\">Test Adding a Note</h3><p>Rerun your server and React app if they're not running. Then, open the website again at <code class=\"language-text\">localhost:3000</code>. Click on the plus button and a pop up will open with the form to add a new note.</p><figure class=\"kg-card kg-image-card\"><img src=\"https://backend.shahednasser.com/content/images/2022/07/Screen-Shot-2022-07-24-at-6.31.41-PM.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"1494\" height=\"792\" srcset=\"https://backend.shahednasser.com/content/images/size/w600/2022/07/Screen-Shot-2022-07-24-at-6.31.41-PM.png 600w, https://backend.shahednasser.com/content/images/size/w1000/2022/07/Screen-Shot-2022-07-24-at-6.31.41-PM.png 1000w, https://backend.shahednasser.com/content/images/2022/07/Screen-Shot-2022-07-24-at-6.31.41-PM.png 1494w\" sizes=\"(min-width: 720px) 720px\"></figure><p>Enter a random title and content then click Add. The pop up form will then close and you can see the new note added.</p><figure class=\"kg-card kg-image-card\"><img src=\"https://backend.shahednasser.com/content/images/2022/07/Screen-Shot-2022-07-24-at-6.32.53-PM.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"1418\" height=\"720\" srcset=\"https://backend.shahednasser.com/content/images/size/w600/2022/07/Screen-Shot-2022-07-24-at-6.32.53-PM.png 600w, https://backend.shahednasser.com/content/images/size/w1000/2022/07/Screen-Shot-2022-07-24-at-6.32.53-PM.png 1000w, https://backend.shahednasser.com/content/images/2022/07/Screen-Shot-2022-07-24-at-6.32.53-PM.png 1418w\" sizes=\"(min-width: 720px) 720px\"></figure><h3 id=\"implement-delete-note-functionality\">Implement Delete Note Functionality</h3><p>The last functionality you'll add is deleting notes. Deleting a note is another act of mutation as it manipulates the server's data.</p><p>At the beginning of the <code class=\"language-text\">App</code> component in <code class=\"language-text\">src/app.js</code> add the following code:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">const</span> queryClient <span class=\"token operator\">=</span> <span class=\"token function\">useQueryClient</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n<span class=\"token keyword\">const</span> mutation <span class=\"token operator\">=</span> <span class=\"token function\">useMutation</span><span class=\"token punctuation\">(</span>deleteNote<span class=\"token punctuation\">,</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token function-variable function\">onSuccess</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> queryClient<span class=\"token punctuation\">.</span><span class=\"token function\">invalidateQueries</span><span class=\"token punctuation\">(</span><span class=\"token string\">'notes'</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span></code></pre></div><p>Here, you get access to the query client using <code class=\"language-text\">useQueryClient</code>. Then, you create a new mutation using <code class=\"language-text\">useMutation</code>. You pass it the function <code class=\"language-text\">deleteNote</code> (which you'll create next) as a first parameter and an object of options. </p><p>To the <code class=\"language-text\">onSuccess</code> option you pass a function that does one thing. It executes the method <code class=\"language-text\">queryClient.invalidateQueries</code>. This method marks the cached data for a specific key as outdated, which triggers retrieving the data again. </p><p>So, once a note is deleted, the query you created earlier that executes the function <code class=\"language-text\">fetchNotes</code> will be triggered and the notes will be fetched again. If you had created other queries on your website that use the same key <code class=\"language-text\">notes</code>, they'll also be triggered to update their data. </p><p>Next, add the function <code class=\"language-text\">deleteNote</code> in the <code class=\"language-text\">App</code> component in the same file:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">function</span> <span class=\"token function\">deleteNote</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">note</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">return</span> <span class=\"token function\">fetch</span><span class=\"token punctuation\">(</span><span class=\"token template-string\"><span class=\"token template-punctuation string\">`</span><span class=\"token string\">http://localhost:3001/notes/</span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${</span>note<span class=\"token punctuation\">.</span>id<span class=\"token interpolation-punctuation punctuation\">}</span></span><span class=\"token template-punctuation string\">`</span></span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">{</span>\n      <span class=\"token literal-property property\">method</span><span class=\"token operator\">:</span> <span class=\"token string\">'DELETE'</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">.</span><span class=\"token function\">then</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">response</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> response<span class=\"token punctuation\">.</span><span class=\"token function\">json</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">.</span><span class=\"token function\">then</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token parameter\"><span class=\"token punctuation\">{</span> success<span class=\"token punctuation\">,</span> message <span class=\"token punctuation\">}</span></span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n      <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">!</span>success<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">throw</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Error</span><span class=\"token punctuation\">(</span>message<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n      <span class=\"token punctuation\">}</span>\n\n      <span class=\"token function\">alert</span><span class=\"token punctuation\">(</span>message<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">}</span></code></pre></div><p>This function receives the <code class=\"language-text\">note</code> to be deleted as a parameter. It sends a <code class=\"language-text\">DELETE</code> request to <code class=\"language-text\">localhost:3001/notes/:id</code>. If the <code class=\"language-text\">success</code> body parameter of the response is <code class=\"language-text\">false</code>, an error is thrown. Otherwise, only an alert is shown.</p><p>Then, in the returned JSX of the <code class=\"language-text\">App</code> component, change how the loading icon and error where shown previously to the following:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token punctuation\">{</span><span class=\"token punctuation\">(</span>isLoading <span class=\"token operator\">||</span> mutation<span class=\"token punctuation\">.</span>isLoading<span class=\"token punctuation\">)</span> <span class=\"token operator\">&#x26;&#x26;</span> <span class=\"token operator\">&#x3C;</span>RefreshIcon className<span class=\"token operator\">=</span><span class=\"token string\">\"w-10 h-10 animate-spin mx-auto\"</span><span class=\"token operator\">></span><span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>RefreshIcon<span class=\"token operator\">></span><span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">{</span><span class=\"token punctuation\">(</span>isError <span class=\"token operator\">||</span> mutation<span class=\"token punctuation\">.</span>isError<span class=\"token punctuation\">)</span> <span class=\"token operator\">&#x26;&#x26;</span> <span class=\"token operator\">&#x3C;</span>span className<span class=\"token operator\">=</span><span class=\"token string\">'text-red'</span><span class=\"token operator\">></span><span class=\"token punctuation\">{</span>error <span class=\"token operator\">?</span> <span class=\"token punctuation\">(</span>error<span class=\"token punctuation\">.</span>message <span class=\"token operator\">?</span> error<span class=\"token punctuation\">.</span>message <span class=\"token operator\">:</span> error<span class=\"token punctuation\">)</span> <span class=\"token operator\">:</span> mutation<span class=\"token punctuation\">.</span>error<span class=\"token punctuation\">.</span>message<span class=\"token punctuation\">}</span><span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>span<span class=\"token operator\">></span><span class=\"token punctuation\">}</span></code></pre></div><p>This shows the loading icon or the error message for both the query that fetches the notes and the mutation that handles deleting a note.</p><p>Finally, find the delete button of a note and add an <code class=\"language-text\">onClick</code> handler:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token operator\">&#x3C;</span>button className<span class=\"token operator\">=</span><span class=\"token string\">'link text-gray-400'</span> onClick<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> mutation<span class=\"token punctuation\">.</span><span class=\"token function\">mutate</span><span class=\"token punctuation\">(</span>note<span class=\"token punctuation\">)</span><span class=\"token punctuation\">}</span><span class=\"token operator\">></span>Delete<span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>button<span class=\"token operator\">></span></code></pre></div><p>On click, the mutation responsible for deleting the note is triggered using <code class=\"language-text\">mutation.mutate</code>. You pass it the note to delete which is the current note in a <code class=\"language-text\">map</code> loop.</p><h3 id=\"test-deleting-a-note\">Test Deleting a Note</h3><p>Rerun your server and React app if they're not running. Then, open the website again at <code class=\"language-text\">localhost:3000</code>. Click the Delete link for any of your notes. If the note is deleted successfully, an alert will be shown.</p><figure class=\"kg-card kg-image-card\"><img src=\"https://backend.shahednasser.com/content/images/2022/07/Screen-Shot-2022-07-01-at-2.48.53-PM.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"1006\" height=\"314\" srcset=\"https://backend.shahednasser.com/content/images/size/w600/2022/07/Screen-Shot-2022-07-01-at-2.48.53-PM.png 600w, https://backend.shahednasser.com/content/images/size/w1000/2022/07/Screen-Shot-2022-07-01-at-2.48.53-PM.png 1000w, https://backend.shahednasser.com/content/images/2022/07/Screen-Shot-2022-07-01-at-2.48.53-PM.png 1006w\" sizes=\"(min-width: 720px) 720px\"></figure><p>After closing the alert, the notes will be fetched again and displayed, if there are any other notes.</p><figure class=\"kg-card kg-image-card\"><img src=\"https://backend.shahednasser.com/content/images/2022/07/Screen-Shot-2022-06-28-at-9.10.04-PM-1.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"1446\" height=\"490\" srcset=\"https://backend.shahednasser.com/content/images/size/w600/2022/07/Screen-Shot-2022-06-28-at-9.10.04-PM-1.png 600w, https://backend.shahednasser.com/content/images/size/w1000/2022/07/Screen-Shot-2022-06-28-at-9.10.04-PM-1.png 1000w, https://backend.shahednasser.com/content/images/2022/07/Screen-Shot-2022-06-28-at-9.10.04-PM-1.png 1446w\" sizes=\"(min-width: 720px) 720px\"></figure><h2 id=\"conclusion\">Conclusion</h2><p>Using React (TanStack) Query, you can easily handle server data fetching and manipulation on your website with advanced features such as caching and synchronization across your React app.</p><p>Make sure to check out the <a href=\"https://tanstack.com/query/v4\">official documentation</a> to learn more about what you can do with React Query.</p>","htmlAst":{"type":"root","children":[{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"React Query (now rebranded to TanStack Query) is a React library used to make fetching and manipulating server-side data easier. Using React Query, you can implement, along with data fetching, caching, and synchronization of your data with the server."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"In this tutorial, you'll build a simple Node.js server and then learn how to interact with it on a React website using React Query."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Please note that this version uses v4 of React Query which is now named TanStack Query."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"You can find the code for this tutorial in "},{"type":"element","tagName":"a","properties":{"href":"https://github.com/shahednasser/react-query-tutorial"},"children":[{"type":"text","value":"this GitHub repository"}]},{"type":"text","value":"."}]},{"type":"element","tagName":"h2","properties":{"id":"prerequisites"},"children":[{"type":"text","value":"Prerequisites"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":" Before starting with this tutorial make sure you have "},{"type":"element","tagName":"a","properties":{"href":"https://nodejs.org/en/"},"children":[{"type":"text","value":"Node.js installed"}]},{"type":"text","value":". You need at least version 14."}]},{"type":"element","tagName":"h2","properties":{"id":"server-setup"},"children":[{"type":"text","value":"Server Setup"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"In this section, you'll set up a simple Node.js server with an SQLite database. The server has 3 endpoints to fetch, add, and delete notes."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"If you already have a server you can skip this section and go to the Website Setup section."}]},{"type":"element","tagName":"h3","properties":{"id":"create-server-project"},"children":[{"type":"text","value":"Create Server Project"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Create a new directory called "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"server"}]},{"type":"text","value":" then initialize a new project using NPM:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"bash"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-bash"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-bash"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"mkdir"}]},{"type":"text","value":" server\n"},{"type":"element","tagName":"span","properties":{"className":["token","builtin","class-name"]},"children":[{"type":"text","value":"cd"}]},{"type":"text","value":" server\n"},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"npm"}]},{"type":"text","value":" init -y"}]}]}]},{"type":"element","tagName":"h3","properties":{"id":"install-dependencies"},"children":[{"type":"text","value":"Install Dependencies"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Then, install the packages you'll need for the development of the server:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"bash"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-bash"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-bash"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"npm"}]},{"type":"text","value":" i express cors body-parser sqlite3 nodemon"}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Here's what each of the packages is for:"}]},{"type":"element","tagName":"ol","properties":{},"children":[{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"express"}]},{"type":"text","value":" to create a server using "},{"type":"element","tagName":"a","properties":{"href":"https://expressjs.com/"},"children":[{"type":"text","value":"Express"}]},{"type":"text","value":"."}]},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"cors"}]},{"type":"text","value":" is an Express middleware used to handle "},{"type":"element","tagName":"a","properties":{"href":"https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS"},"children":[{"type":"text","value":"CORS"}]},{"type":"text","value":" on your server."}]},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"body-parser"}]},{"type":"text","value":" is an Express middleware used to parse the body of a request."}]},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"sqlite3"}]},{"type":"text","value":" is an SQLite database adapter for Node.js."}]},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"nodemon"}]},{"type":"text","value":" is a library used to restart the server whenever new changes occur to the files."}]}]},{"type":"element","tagName":"h3","properties":{"id":"create-server"},"children":[{"type":"text","value":"Create Server"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Create the file "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"index.js"}]},{"type":"text","value":" with the following content:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" express "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"require"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'express'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" app "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"express"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" port "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"3001"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" cors "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"require"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'cors'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" sqlite3 "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"require"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'sqlite3'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"verbose"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" bodyParser "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"require"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'body-parser'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n\napp"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"use"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"bodyParser"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"json"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\napp"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"use"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"cors"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n\napp"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"listen"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"port"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n  console"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"log"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","template-string"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","template-punctuation","string"]},"children":[{"type":"text","value":"`"}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"Notes app listening on port "}]},{"type":"element","tagName":"span","properties":{"className":["token","interpolation"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","interpolation-punctuation","punctuation"]},"children":[{"type":"text","value":"${"}]},{"type":"text","value":"port"},{"type":"element","tagName":"span","properties":{"className":["token","interpolation-punctuation","punctuation"]},"children":[{"type":"text","value":"}"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","template-punctuation","string"]},"children":[{"type":"text","value":"`"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"This initializes the server using Express on port "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"3001"}]},{"type":"text","value":". It also uses the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"cors"}]},{"type":"text","value":" and "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"body-parser"}]},{"type":"text","value":" middleware."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Then, in "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"package.json"}]},{"type":"text","value":" add a new script "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"start"}]},{"type":"text","value":" to run the server:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"json"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-json"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-json"]},"children":[{"type":"text","value":"  "},{"type":"element","tagName":"span","properties":{"className":["token","property"]},"children":[{"type":"text","value":"\"scripts\""}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","property"]},"children":[{"type":"text","value":"\"start\""}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"nodemon index.js\""}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]}]}]}]},{"type":"element","tagName":"h3","properties":{"id":"initialize-the-database"},"children":[{"type":"text","value":"Initialize the Database"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"In "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"index.js"}]},{"type":"text","value":" before "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"app.listen"}]},{"type":"text","value":" add the following code:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" db "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"new"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","class-name"]},"children":[{"type":"text","value":"sqlite3"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"Database"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'data.db'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"err"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"if"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"err"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"throw"}]},{"type":"text","value":" err"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n\n  "},{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"// create tables if they don't exist"}]},{"type":"text","value":"\n  db"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"serialize"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n    db"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"run"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","template-string"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","template-punctuation","string"]},"children":[{"type":"text","value":"`"}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"CREATE TABLE IF NOT EXISTS notes (id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT, content TEXT, \n      created_at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP)"}]},{"type":"element","tagName":"span","properties":{"className":["token","template-punctuation","string"]},"children":[{"type":"text","value":"`"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"This creates a new database if it doesn't exist in the file "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"data.db"}]},{"type":"text","value":". Then, if the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"notes"}]},{"type":"text","value":" table doesn't exist on the database it creates it as well."}]},{"type":"element","tagName":"h3","properties":{"id":"add-endpoints"},"children":[{"type":"text","value":"Add Endpoints"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Following the database code, add the following code to add the endpoints:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"text","value":"app"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"get"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'/notes'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"req"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" res"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n  db"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"all"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'SELECT * FROM notes'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"err"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" rows"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"if"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"err"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n      console"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"error"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"err"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" res"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"status"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"500"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"json"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"success"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","boolean"]},"children":[{"type":"text","value":"false"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"message"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'An error occurred, please try again later'"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n\n    "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" res"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"json"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"success"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","boolean"]},"children":[{"type":"text","value":"true"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"data"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" rows "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n\napp"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"get"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'/notes/:id'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"req"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" res"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n  db"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"get"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'SELECT * FROM notes WHERE id = ?'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" req"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"params"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"id"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"err"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" row"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"if"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"err"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n      console"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"error"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"err"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" res"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"status"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"500"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"json"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"success"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","boolean"]},"children":[{"type":"text","value":"false"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"message"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'An error occurred, please try again later'"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n\n    "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"if"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"!"}]},{"type":"text","value":"row"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" res"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"status"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"404"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"json"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"success"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","boolean"]},"children":[{"type":"text","value":"false"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"message"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'Note does not exist'"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n\n    "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" res"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"json"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"success"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","boolean"]},"children":[{"type":"text","value":"true"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"data"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" row "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n\napp"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"post"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'/notes'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"req"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" res"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" title"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" content "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" req"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"body"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n\n  "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"if"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"!"}]},{"type":"text","value":"title "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"||"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"!"}]},{"type":"text","value":"content"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" res"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"status"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"400"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"json"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"success"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","boolean"]},"children":[{"type":"text","value":"false"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"message"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'title and content are required'"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n\n  db"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"run"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'INSERT INTO notes (title, content) VALUES (?, ?)'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"["}]},{"type":"text","value":"title"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" content"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"]"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"function"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"err"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"if"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"err"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n      console"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"error"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"err"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" res"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"status"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"500"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"json"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"success"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","boolean"]},"children":[{"type":"text","value":"false"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"message"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'An error occurred, please try again later'"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n\n    "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" res"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"json"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"success"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","boolean"]},"children":[{"type":"text","value":"true"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"data"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"id"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"this"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"lastID"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n        title"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n        content"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n\napp"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"delete"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'/notes/:id'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"req"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" res"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" id "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" req"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"params"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n\n  db"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"get"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'SELECT * FROM notes WHERE id = ?'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"["}]},{"type":"text","value":"id"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"]"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"err"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" row"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"if"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"err"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n      console"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"error"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"err"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" res"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"status"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"500"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"json"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"success"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","boolean"]},"children":[{"type":"text","value":"false"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"message"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'An error occurred, please try again later'"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n\n    "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"if"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"!"}]},{"type":"text","value":"row"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" res"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"status"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"404"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"json"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"success"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","boolean"]},"children":[{"type":"text","value":"false"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"message"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'Note does not exist'"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n\n    db"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"run"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'DELETE FROM notes WHERE id = ?'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"["}]},{"type":"text","value":"id"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"]"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"error"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"if"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"error"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n        console"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"error"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"error"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" res"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"status"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"500"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"json"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"success"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","boolean"]},"children":[{"type":"text","value":"false"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"message"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'An error occurred, please try again later'"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n\n      "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" res"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"json"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"success"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","boolean"]},"children":[{"type":"text","value":"true"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"message"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'Note deleted successfully'"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Briefly, this creates 4 endpoints:"}]},{"type":"element","tagName":"ol","properties":{},"children":[{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"/notes"}]},{"type":"text","value":" endpoint of the method "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"GET"}]},{"type":"text","value":" to fetch all notes."}]},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"/notes/:id"}]},{"type":"text","value":" endpoint of the method "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"GET"}]},{"type":"text","value":" to fetch a note by an ID."}]},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"/notes"}]},{"type":"text","value":" endpoint of the method "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"POST"}]},{"type":"text","value":" to add a note."}]},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"/notes/:id"}]},{"type":"text","value":" endpoint of the method "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"DELETE"}]},{"type":"text","value":" to delete a note."}]}]},{"type":"element","tagName":"h3","properties":{"id":"test-server"},"children":[{"type":"text","value":"Test Server"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Run the following command to start the server:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"bash"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-bash"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-bash"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"npm"}]},{"type":"text","value":" start"}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"This starts the server on port "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"3001"}]},{"type":"text","value":". You can test it out by sending a request to "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"localhost:3001/notes"}]},{"type":"text","value":"."}]},{"type":"element","tagName":"h2","properties":{"id":"website-setup"},"children":[{"type":"text","value":"Website Setup"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"In this section, you'll create the website with Create React App (CRA). This is where you'll make use of React Query."}]},{"type":"element","tagName":"h3","properties":{"id":"create-website-project"},"children":[{"type":"text","value":"Create Website Project"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"To create a new React app, run the following command in a different directory:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"bash"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-bash"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-bash"]},"children":[{"type":"text","value":"npx create-react-app website"}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"This creates a new React app in the directory "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"website"}]},{"type":"text","value":"."}]},{"type":"element","tagName":"h3","properties":{"id":"install-dependencies-1"},"children":[{"type":"text","value":"Install Dependencies"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Run the following command to change to the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"website"}]},{"type":"text","value":" directory and install the necessary dependencies for the website:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"bash"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-bash"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-bash"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","builtin","class-name"]},"children":[{"type":"text","value":"cd"}]},{"type":"text","value":" website\n"},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"npm"}]},{"type":"text","value":" i @tanstack/react-query tailwindcss postcss autoprefixer @tailwindcss/typography @heroicons/react @windmill/react-ui"}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"The "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"@tanstack/react-query"}]},{"type":"text","value":" library is the React Query library which is now named TanStack Query. The other libraries are "},{"type":"element","tagName":"a","properties":{"href":"https://tailwindcss.com/"},"children":[{"type":"text","value":"Tailwind CSS"}]},{"type":"text","value":" related libraries to add styling to the website."}]},{"type":"element","tagName":"h3","properties":{"id":"tailwind-css-setup"},"children":[{"type":"text","value":"Tailwind CSS Setup"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"This section is optional and is only used to set up Tailwind CSS."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Create the file "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"postcss.config.js"}]},{"type":"text","value":" with the following content:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"text","value":"module"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"exports "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"plugins"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"tailwindcss"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"autoprefixer"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n"}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Also, create the file "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"tailwind.config.js"}]},{"type":"text","value":" with the following content:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"/** @type {import('tailwindcss').Config} */"}]},{"type":"text","value":"\nmodule"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"exports "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"content"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"["}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"./src/**/*.{js,jsx,ts,tsx}\""}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"]"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"theme"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"extend"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"plugins"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"["}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"require"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'@tailwindcss/typography'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"]"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n"}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Then, create the file "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"src/index.css"}]},{"type":"text","value":" with the following content:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"css"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-css"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-css"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","atrule"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","rule"]},"children":[{"type":"text","value":"@tailwind"}]},{"type":"text","value":" base"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","atrule"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","rule"]},"children":[{"type":"text","value":"@tailwind"}]},{"type":"text","value":" components"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","atrule"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","rule"]},"children":[{"type":"text","value":"@tailwind"}]},{"type":"text","value":" utilities"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]}]}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Finally, in "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"index.js"}]},{"type":"text","value":" import "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"src/index.css"}]},{"type":"text","value":" at the beginning of the file:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"import"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'./index.css'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]}]}]}]},{"type":"element","tagName":"h3","properties":{"id":"use-queryclientprovider"},"children":[{"type":"text","value":"Use QueryClientProvider"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"To use the React Query client in all of your components, you must use it at a high level in your website's components hierarchy. The best place to put it is in "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"src/index.js"}]},{"type":"text","value":" which wraps up your entire website's components."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"In "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"src/index.js"}]},{"type":"text","value":" add the following imports at the beginning of the file:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"import"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n  QueryClient"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n  QueryClientProvider"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"from"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'@tanstack/react-query'"}]}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Then, initialize a new Query client:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" queryClient "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"new"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","class-name"]},"children":[{"type":"text","value":"QueryClient"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Finally, change the parameter passed to "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"root.render"}]},{"type":"text","value":":"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"text","value":"root"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"render"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"QueryClientProvider client"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"queryClient"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"App "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"QueryClientProvider"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"This wraps the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"App"}]},{"type":"text","value":" component which holds the rest of the website's components with "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"QueryClientProvider"}]},{"type":"text","value":". This provider accepts the prop "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"client"}]},{"type":"text","value":" which is an instance of "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"QueryClient"}]},{"type":"text","value":"."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Now, all components within the website will have access to the Query Client which is used to fetch, cache, and manipulate the server data."}]},{"type":"element","tagName":"h3","properties":{"id":"implement-display-notes"},"children":[{"type":"text","value":"Implement Display Notes"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Fetching data from the server is an act of performing a query. Therefore, you'll use "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"useQuery"}]},{"type":"text","value":" in this section."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"You'll display notes in the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"App"}]},{"type":"text","value":" component. These notes are fetched from the server using the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"/notes"}]},{"type":"text","value":" endpoint."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Replace the content of "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"app.js"}]},{"type":"text","value":" with the following content:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"import"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" PlusIcon"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" RefreshIcon "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"from"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'@heroicons/react/solid'"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"import"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" useMutation"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" useQuery"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" useQueryClient "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"from"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'@tanstack/react-query'"}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"function"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"App"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" isLoading"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" isError"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" data"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" error "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"useQuery"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"["}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'notes'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"]"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" fetchNotes"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n\n  "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"function"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"fetchNotes"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"fetch"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'http://localhost:3001/notes'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"then"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"response"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" response"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"json"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"then"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" success"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" data "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"if"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"!"}]},{"type":"text","value":"success"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"throw"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"new"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","class-name"]},"children":[{"type":"text","value":"Error"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'An error occurred while fetching notes'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" data"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n\n  "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"div className"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"w-screen h-screen overflow-x-hidden bg-red-400 flex flex-col justify-center items-center\""}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"div className"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'bg-white w-full md:w-1/2 p-5 text-center rounded shadow-md text-gray-800 prose'"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"h1"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"Notes"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"h1"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"isLoading "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"&&"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"RefreshIcon className"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"w-10 h-10 animate-spin mx-auto\""}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"RefreshIcon"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"isError "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"&&"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"span className"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'text-red'"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"error"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"message "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"?"}]},{"type":"text","value":" error"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"message "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" error"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"span"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"!"}]},{"type":"text","value":"isLoading "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"&&"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"!"}]},{"type":"text","value":"isError "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"&&"}]},{"type":"text","value":" data "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"&&"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"!"}]},{"type":"text","value":"data"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"length "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"&&"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"span className"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'text-red-400'"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"You have no notes"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"span"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"data "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"&&"}]},{"type":"text","value":" data"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"length "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"0"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"&&"}]},{"type":"text","value":" data"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"map"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"note"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" index"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"\n          "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"div key"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"note"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"id"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" className"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"element","tagName":"span","properties":{"className":["token","template-string"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","template-punctuation","string"]},"children":[{"type":"text","value":"`"}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"text-left "}]},{"type":"element","tagName":"span","properties":{"className":["token","interpolation"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","interpolation-punctuation","punctuation"]},"children":[{"type":"text","value":"${"}]},{"type":"text","value":"index "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"!=="}]},{"type":"text","value":" data"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"length "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"-"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"1"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"?"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'border-b pb-2'"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"''"}]},{"type":"element","tagName":"span","properties":{"className":["token","interpolation-punctuation","punctuation"]},"children":[{"type":"text","value":"}"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","template-punctuation","string"]},"children":[{"type":"text","value":"`"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n            "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"h2"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"note"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"title"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"h2"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n            "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"p"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"note"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"content"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"p"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n            "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"span"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n              "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"button className"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'link text-gray-400'"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"Delete"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"button"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n            "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"span"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n          "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"div"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"div"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"button className"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"mt-2 bg-gray-700 hover:bg-gray-600 rounded-full text-white p-3\""}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"PlusIcon className"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'w-5 h-5'"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"PlusIcon"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"button"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"div"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"export"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"default"}]},{"type":"text","value":" App"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Here's briefly what's going on in this code snippet:"}]},{"type":"element","tagName":"ol","properties":{},"children":[{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"You use "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"useQuery"}]},{"type":"text","value":" to fetch the notes. The first parameter it accepts is a unique key used for caching. The second parameter is the function used to fetch the data. You pass it the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"fetchNotes"}]},{"type":"text","value":" function."}]},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"useQuery"}]},{"type":"text","value":" returns an object that holds "},{"type":"element","tagName":"a","properties":{"href":"https://tanstack.com/query/v4/docs/reference/useQuery"},"children":[{"type":"text","value":"many variables"}]},{"type":"text","value":". Here, you use 4 of them: "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"isLoading"}]},{"type":"text","value":" is a boolean value that determines whether the data is currently being fetched; "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"isError"}]},{"type":"text","value":" is a boolean value that determines if an error occurred. "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"data"}]},{"type":"text","value":" is the data that is fetched from the server; and "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"error"}]},{"type":"text","value":" is the error message if "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"isError"}]},{"type":"text","value":" is true."}]},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"The "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"fetchNotes"}]},{"type":"text","value":" function must return a promise that either resolves data or throws an error. In the function, you send a "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"GET"}]},{"type":"text","value":" request to "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"localhost:3001/notes"}]},{"type":"text","value":" to fetch the notes. If the data is fetched successfully it is returned in the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"then"}]},{"type":"text","value":" fulfillment function. "}]},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"In the returned JSX, if "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"isLoading"}]},{"type":"text","value":" is true, a loading icon is shown. If "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"isError"}]},{"type":"text","value":" is true, an error message is shown. If "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"data"}]},{"type":"text","value":" is fetched successfully and has any data in it, the notes are rendered."}]},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"You also show a button with a plus icon to add new notes. You'll implement this later."}]}]},{"type":"element","tagName":"h3","properties":{"id":"test-displaying-notes"},"children":[{"type":"text","value":"Test Displaying Notes"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"To test out what you've implemented so far, make sure your server is still running, then start your React app server with the following command:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"bash"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-bash"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-bash"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"npm"}]},{"type":"text","value":" start"}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"This runs your React app on "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"localhost:3000"}]},{"type":"text","value":" by default. If you open it in your browser, you'll see a loading icon at first then you'll see no notes as you haven't added any yet."}]},{"type":"element","tagName":"figure","properties":{"className":["kg-card","kg-image-card"]},"children":[{"type":"element","tagName":"img","properties":{"src":"https://backend.shahednasser.com/content/images/2022/07/Screen-Shot-2022-06-28-at-9.10.04-PM.png","className":["kg-image"],"alt":"","loading":"lazy","width":1446,"height":490,"srcSet":["https://backend.shahednasser.com/content/images/size/w600/2022/07/Screen-Shot-2022-06-28-at-9.10.04-PM.png 600w","https://backend.shahednasser.com/content/images/size/w1000/2022/07/Screen-Shot-2022-06-28-at-9.10.04-PM.png 1000w","https://backend.shahednasser.com/content/images/2022/07/Screen-Shot-2022-06-28-at-9.10.04-PM.png 1446w"],"sizes":"(min-width: 720px) 720px"},"children":[]}]},{"type":"element","tagName":"h3","properties":{"id":"implement-add-notes-functionality"},"children":[{"type":"text","value":"Implement Add Notes Functionality"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Adding a note is an act of mutation on the server data. Therefore, you'll be using the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"useMutation"}]},{"type":"text","value":" hook in this section."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"You'll create a separate component that shows the form used to add a note."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Create the file "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"src/form.js"}]},{"type":"text","value":" with the following content:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"import"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" useMutation"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" useQueryClient "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"from"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'@tanstack/react-query'"}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"import"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" useState "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"from"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'react'"}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"export"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"default"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"function"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"Form"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" isOpen"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" setIsOpen "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"["}]},{"type":"text","value":"title"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" setTitle"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"]"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"useState"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"\""}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"["}]},{"type":"text","value":"content"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" setContent"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"]"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"useState"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"\""}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" queryClient "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"useQueryClient"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n\n  "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" mutation "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"useMutation"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"insertNote"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","function-variable","function"]},"children":[{"type":"text","value":"onSuccess"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"setTitle"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"\""}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"setContent"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"\""}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n\n  "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"function"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"closeForm"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"e"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n    e"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"preventDefault"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"setIsOpen"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","boolean"]},"children":[{"type":"text","value":"false"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n\n  "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"function"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"insertNote"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"fetch"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","template-string"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","template-punctuation","string"]},"children":[{"type":"text","value":"`"}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"http://localhost:3001/notes"}]},{"type":"element","tagName":"span","properties":{"className":["token","template-punctuation","string"]},"children":[{"type":"text","value":"`"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"method"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'POST'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"headers"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","string-property","property"]},"children":[{"type":"text","value":"'Content-Type'"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'application/json'"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"body"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","constant"]},"children":[{"type":"text","value":"JSON"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"stringify"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n        title"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n        content\n      "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"then"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"response"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" response"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"json"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"then"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" success"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" data "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"if"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"!"}]},{"type":"text","value":"success"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"throw"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"new"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","class-name"]},"children":[{"type":"text","value":"Error"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"An error occured\""}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n      \n      "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"setIsOpen"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","boolean"]},"children":[{"type":"text","value":"false"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n      queryClient"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"setQueriesData"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'notes'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"old"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"["}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"..."}]},{"type":"text","value":"old"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" data"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"]"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n\n  "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"function"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"handleSubmit"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"e"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n    e"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"preventDefault"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n    mutation"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"mutate"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n\n  "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"div className"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"element","tagName":"span","properties":{"className":["token","template-string"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","template-punctuation","string"]},"children":[{"type":"text","value":"`"}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"absolute w-full h-full top-0 left-0 z-50 flex justify-center items-center "}]},{"type":"element","tagName":"span","properties":{"className":["token","interpolation"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","interpolation-punctuation","punctuation"]},"children":[{"type":"text","value":"${"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"!"}]},{"type":"text","value":"isOpen "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"?"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'hidden'"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"''"}]},{"type":"element","tagName":"span","properties":{"className":["token","interpolation-punctuation","punctuation"]},"children":[{"type":"text","value":"}"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","template-punctuation","string"]},"children":[{"type":"text","value":"`"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"div className"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'bg-black opacity-50 absolute w-full h-full top-0 left-0'"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"div"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"form className"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'bg-white w-full md:w-1/2 p-5 rounded shadow-md text-gray-800 prose relative'"}]},{"type":"text","value":" \n        onSubmit"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"handleSubmit"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"h2 className"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'text-center'"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"Add Note"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"h2"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"mutation"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"isError "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"&&"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"span className"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'block mb-2 text-red-400'"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"mutation"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"error"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"message "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"?"}]},{"type":"text","value":" mutation"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"error"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"message "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" mutation"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"error"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"span"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"input type"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"text\""}]},{"type":"text","value":" placeholder"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'Title'"}]},{"type":"text","value":" className"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'rounded-sm w-full border px-2'"}]},{"type":"text","value":" \n          value"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"title"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" onChange"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"e"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"setTitle"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"e"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"target"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"value"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"textarea onChange"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"e"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"setContent"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"e"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"target"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"value"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" \n          className"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"rounded-sm w-full border px-2 mt-2\""}]},{"type":"text","value":" placeholder"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'Content'"}]},{"type":"text","value":" value"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"content"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"textarea"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"div"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n          "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"button type"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"submit\""}]},{"type":"text","value":" className"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'mt-2 bg-red-400 hover:bg-red-600 text-white p-3 rounded mr-2 disabled:pointer-events-none'"}]},{"type":"text","value":" \n            disabled"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"mutation"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"isLoading"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n            Add"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"button"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n          "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"button className"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'mt-2 bg-gray-700 hover:bg-gray-600 text-white p-3 rounded'"}]},{"type":"text","value":"\n            onClick"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"closeForm"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"Cancel"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"button"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"div"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"form"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"div"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Here's a brief explanation of this form"}]},{"type":"element","tagName":"ol","properties":{},"children":[{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"This form acts as a pop-up. It accepts "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"isOpen"}]},{"type":"text","value":" and "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"setIsOpen"}]},{"type":"text","value":" props to determine when the form is opened and handle closing it."}]},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"You use "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"useQueryClient"}]},{"type":"text","value":" to get access to the Query Client. This is necessary to perform a mutation."}]},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"To handle adding a note on your server and keep all data in your query client synced, you must the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"useMutation"}]},{"type":"text","value":" hook. "}]},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"The "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"useMutation"}]},{"type":"text","value":" hook accepts 2 parameters. Thie first one is the function that will handle the mutation, which in this case is "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"insertNote"}]},{"type":"text","value":". The second parameter is an object of "},{"type":"element","tagName":"a","properties":{"href":"https://tanstack.com/query/v4/docs/reference/useMutation"},"children":[{"type":"text","value":"options"}]},{"type":"text","value":". You pass it one option "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"onSuccess"}]},{"type":"text","value":" which is a function that runs if the mutation is performed successfully. You use this to reset the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"title"}]},{"type":"text","value":" and "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"content"}]},{"type":"text","value":" fields of the form."}]},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"In "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"insertNote"}]},{"type":"text","value":", you send a "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"POST"}]},{"type":"text","value":" request to "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"localhost:3001/notes"}]},{"type":"text","value":" and pass in the body the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"title"}]},{"type":"text","value":" and "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"content"}]},{"type":"text","value":" of the note to be created. If the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"success"}]},{"type":"text","value":" body parameter returned from the server is "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"false"}]},{"type":"text","value":", an error is thrown to signal that the mutation failed. "}]},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"If the note is added successfully, you change the cached value of the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"notes"}]},{"type":"text","value":" key using the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"queryClient.setQueriesData"}]},{"type":"text","value":" method. This method accepts the key as a first parameter and the new data associated with that key as a second parameter. This updates the data everywhere it's used on your website."}]},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"In this component you display a form with 2 fields: "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"title"}]},{"type":"text","value":" and "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"content"}]},{"type":"text","value":". In the form, you check if an error occurs using "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"mutation.isError"}]},{"type":"text","value":" and get access to the error using "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"mutation.error"}]},{"type":"text","value":"."}]},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"You handle form submission in the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"handleSubmit"}]},{"type":"text","value":" function. Here, you trigger the mutation using "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"mutation.mutate"}]},{"type":"text","value":". This is where the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"insertNote"}]},{"type":"text","value":" function is triggered to add a new note."}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Then, in "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"src/app.js"}]},{"type":"text","value":" add the following imports at the beginning of the file:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"import"}]},{"type":"text","value":" Form "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"from"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'./form'"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"import"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" useState "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"from"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'react'"}]}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Then, at the beginning of the component add a new state variable to manage wheter the form is opened or not:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"["}]},{"type":"text","value":"isOpen"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" setIsOpen"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"]"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"useState"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","boolean"]},"children":[{"type":"text","value":"false"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Next, add a new function "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"addNote"}]},{"type":"text","value":" that just uses "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"setIsOpen"}]},{"type":"text","value":" to open the form:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"function"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"addNote"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"setIsOpen"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","boolean"]},"children":[{"type":"text","value":"true"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Finally, in the returned JSX, replace the button with the plus icon with the following:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"button className"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"mt-2 bg-gray-700 hover:bg-gray-600 rounded-full text-white p-3\""}]},{"type":"text","value":" onClick"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"addNote"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"PlusIcon className"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'w-5 h-5'"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"PlusIcon"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"button"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"Form isOpen"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"isOpen"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" setIsOpen"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"setIsOpen"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"This sets the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"onClick"}]},{"type":"text","value":" handler of the button to "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"addNote"}]},{"type":"text","value":". It also adds the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"Form"}]},{"type":"text","value":" component you created earlier as a child component of "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"App"}]},{"type":"text","value":". "}]},{"type":"element","tagName":"h3","properties":{"id":"test-adding-a-note"},"children":[{"type":"text","value":"Test Adding a Note"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Rerun your server and React app if they're not running. Then, open the website again at "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"localhost:3000"}]},{"type":"text","value":". Click on the plus button and a pop up will open with the form to add a new note."}]},{"type":"element","tagName":"figure","properties":{"className":["kg-card","kg-image-card"]},"children":[{"type":"element","tagName":"img","properties":{"src":"https://backend.shahednasser.com/content/images/2022/07/Screen-Shot-2022-07-24-at-6.31.41-PM.png","className":["kg-image"],"alt":"","loading":"lazy","width":1494,"height":792,"srcSet":["https://backend.shahednasser.com/content/images/size/w600/2022/07/Screen-Shot-2022-07-24-at-6.31.41-PM.png 600w","https://backend.shahednasser.com/content/images/size/w1000/2022/07/Screen-Shot-2022-07-24-at-6.31.41-PM.png 1000w","https://backend.shahednasser.com/content/images/2022/07/Screen-Shot-2022-07-24-at-6.31.41-PM.png 1494w"],"sizes":"(min-width: 720px) 720px"},"children":[]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Enter a random title and content then click Add. The pop up form will then close and you can see the new note added."}]},{"type":"element","tagName":"figure","properties":{"className":["kg-card","kg-image-card"]},"children":[{"type":"element","tagName":"img","properties":{"src":"https://backend.shahednasser.com/content/images/2022/07/Screen-Shot-2022-07-24-at-6.32.53-PM.png","className":["kg-image"],"alt":"","loading":"lazy","width":1418,"height":720,"srcSet":["https://backend.shahednasser.com/content/images/size/w600/2022/07/Screen-Shot-2022-07-24-at-6.32.53-PM.png 600w","https://backend.shahednasser.com/content/images/size/w1000/2022/07/Screen-Shot-2022-07-24-at-6.32.53-PM.png 1000w","https://backend.shahednasser.com/content/images/2022/07/Screen-Shot-2022-07-24-at-6.32.53-PM.png 1418w"],"sizes":"(min-width: 720px) 720px"},"children":[]}]},{"type":"element","tagName":"h3","properties":{"id":"implement-delete-note-functionality"},"children":[{"type":"text","value":"Implement Delete Note Functionality"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"The last functionality you'll add is deleting notes. Deleting a note is another act of mutation as it manipulates the server's data."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"At the beginning of the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"App"}]},{"type":"text","value":" component in "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"src/app.js"}]},{"type":"text","value":" add the following code:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" queryClient "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"useQueryClient"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" mutation "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"useMutation"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"deleteNote"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","function-variable","function"]},"children":[{"type":"text","value":"onSuccess"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" queryClient"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"invalidateQueries"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'notes'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Here, you get access to the query client using "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"useQueryClient"}]},{"type":"text","value":". Then, you create a new mutation using "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"useMutation"}]},{"type":"text","value":". You pass it the function "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"deleteNote"}]},{"type":"text","value":" (which you'll create next) as a first parameter and an object of options. "}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"To the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"onSuccess"}]},{"type":"text","value":" option you pass a function that does one thing. It executes the method "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"queryClient.invalidateQueries"}]},{"type":"text","value":". This method marks the cached data for a specific key as outdated, which triggers retrieving the data again. "}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"So, once a note is deleted, the query you created earlier that executes the function "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"fetchNotes"}]},{"type":"text","value":" will be triggered and the notes will be fetched again. If you had created other queries on your website that use the same key "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"notes"}]},{"type":"text","value":", they'll also be triggered to update their data. "}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Next, add the function "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"deleteNote"}]},{"type":"text","value":" in the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"App"}]},{"type":"text","value":" component in the same file:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"function"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"deleteNote"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"note"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"fetch"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","template-string"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","template-punctuation","string"]},"children":[{"type":"text","value":"`"}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"http://localhost:3001/notes/"}]},{"type":"element","tagName":"span","properties":{"className":["token","interpolation"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","interpolation-punctuation","punctuation"]},"children":[{"type":"text","value":"${"}]},{"type":"text","value":"note"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"id"},{"type":"element","tagName":"span","properties":{"className":["token","interpolation-punctuation","punctuation"]},"children":[{"type":"text","value":"}"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","template-punctuation","string"]},"children":[{"type":"text","value":"`"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"method"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'DELETE'"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"then"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"response"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" response"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"json"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"then"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" success"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" message "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"if"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"!"}]},{"type":"text","value":"success"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"throw"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"new"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","class-name"]},"children":[{"type":"text","value":"Error"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"message"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n\n      "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"alert"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"message"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"This function receives the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"note"}]},{"type":"text","value":" to be deleted as a parameter. It sends a "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"DELETE"}]},{"type":"text","value":" request to "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"localhost:3001/notes/:id"}]},{"type":"text","value":". If the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"success"}]},{"type":"text","value":" body parameter of the response is "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"false"}]},{"type":"text","value":", an error is thrown. Otherwise, only an alert is shown."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Then, in the returned JSX of the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"App"}]},{"type":"text","value":" component, change how the loading icon and error where shown previously to the following:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"isLoading "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"||"}]},{"type":"text","value":" mutation"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"isLoading"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"&&"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"RefreshIcon className"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"w-10 h-10 animate-spin mx-auto\""}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"RefreshIcon"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"isError "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"||"}]},{"type":"text","value":" mutation"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"isError"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"&&"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"span className"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'text-red'"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"error "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"?"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"error"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"message "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"?"}]},{"type":"text","value":" error"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"message "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" error"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" mutation"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"error"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"message"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"span"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"This shows the loading icon or the error message for both the query that fetches the notes and the mutation that handles deleting a note."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Finally, find the delete button of a note and add an "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"onClick"}]},{"type":"text","value":" handler:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"button className"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'link text-gray-400'"}]},{"type":"text","value":" onClick"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" mutation"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"mutate"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"note"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"Delete"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"button"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"On click, the mutation responsible for deleting the note is triggered using "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"mutation.mutate"}]},{"type":"text","value":". You pass it the note to delete which is the current note in a "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"map"}]},{"type":"text","value":" loop."}]},{"type":"element","tagName":"h3","properties":{"id":"test-deleting-a-note"},"children":[{"type":"text","value":"Test Deleting a Note"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Rerun your server and React app if they're not running. Then, open the website again at "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"localhost:3000"}]},{"type":"text","value":". Click the Delete link for any of your notes. If the note is deleted successfully, an alert will be shown."}]},{"type":"element","tagName":"figure","properties":{"className":["kg-card","kg-image-card"]},"children":[{"type":"element","tagName":"img","properties":{"src":"https://backend.shahednasser.com/content/images/2022/07/Screen-Shot-2022-07-01-at-2.48.53-PM.png","className":["kg-image"],"alt":"","loading":"lazy","width":1006,"height":314,"srcSet":["https://backend.shahednasser.com/content/images/size/w600/2022/07/Screen-Shot-2022-07-01-at-2.48.53-PM.png 600w","https://backend.shahednasser.com/content/images/size/w1000/2022/07/Screen-Shot-2022-07-01-at-2.48.53-PM.png 1000w","https://backend.shahednasser.com/content/images/2022/07/Screen-Shot-2022-07-01-at-2.48.53-PM.png 1006w"],"sizes":"(min-width: 720px) 720px"},"children":[]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"After closing the alert, the notes will be fetched again and displayed, if there are any other notes."}]},{"type":"element","tagName":"figure","properties":{"className":["kg-card","kg-image-card"]},"children":[{"type":"element","tagName":"img","properties":{"src":"https://backend.shahednasser.com/content/images/2022/07/Screen-Shot-2022-06-28-at-9.10.04-PM-1.png","className":["kg-image"],"alt":"","loading":"lazy","width":1446,"height":490,"srcSet":["https://backend.shahednasser.com/content/images/size/w600/2022/07/Screen-Shot-2022-06-28-at-9.10.04-PM-1.png 600w","https://backend.shahednasser.com/content/images/size/w1000/2022/07/Screen-Shot-2022-06-28-at-9.10.04-PM-1.png 1000w","https://backend.shahednasser.com/content/images/2022/07/Screen-Shot-2022-06-28-at-9.10.04-PM-1.png 1446w"],"sizes":"(min-width: 720px) 720px"},"children":[]}]},{"type":"element","tagName":"h2","properties":{"id":"conclusion"},"children":[{"type":"text","value":"Conclusion"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Using React (TanStack) Query, you can easily handle server data fetching and manipulation on your website with advanced features such as caching and synchronization across your React app."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Make sure to check out the "},{"type":"element","tagName":"a","properties":{"href":"https://tanstack.com/query/v4"},"children":[{"type":"text","value":"official documentation"}]},{"type":"text","value":" to learn more about what you can do with React Query."}]}],"data":{"quirksMode":false}},"tableOfContents":[{"id":"prerequisites","heading":"Prerequisites"},{"id":"server-setup","heading":"Server Setup","items":[{"id":"create-server-project","heading":"Create Server Project"},{"id":"install-dependencies","heading":"Install Dependencies"},{"id":"create-server","heading":"Create Server"},{"id":"initialize-the-database","heading":"Initialize the Database"},{"id":"add-endpoints","heading":"Add Endpoints"},{"id":"test-server","heading":"Test Server"}]},{"id":"website-setup","heading":"Website Setup","items":[{"id":"create-website-project","heading":"Create Website Project"},{"id":"install-dependencies-1","heading":"Install Dependencies"},{"id":"tailwind-css-setup","heading":"Tailwind CSS Setup"},{"id":"use-queryclientprovider","heading":"Use QueryClientProvider"},{"id":"implement-display-notes","heading":"Implement Display Notes"},{"id":"test-displaying-notes","heading":"Test Displaying Notes"},{"id":"implement-add-notes-functionality","heading":"Implement Add Notes Functionality"},{"id":"test-adding-a-note","heading":"Test Adding a Note"},{"id":"implement-delete-note-functionality","heading":"Implement Delete Note Functionality"},{"id":"test-deleting-a-note","heading":"Test Deleting a Note"}]},{"id":"conclusion","heading":"Conclusion"}]},"featureImageSharp":{"base":"React--TanStack--Query-Tutorial-for-Beginners.jpg","publicURL":"/static/49810f1cc6a34556c1ce36e3061364ce/React--TanStack--Query-Tutorial-for-Beginners.jpg","imageMeta":{"width":1560,"height":876},"childImageSharp":{"fluid":{"base64":"data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAALABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAECBf/EABQBAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhADEAAAAduqBDD/xAAYEAACAwAAAAAAAAAAAAAAAAAAARESIP/aAAgBAQABBQKxLz//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/AT//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/AT//xAAXEAADAQAAAAAAAAAAAAAAAAAAATEg/9oACAEBAAY/AoyZ/8QAGhABAAIDAQAAAAAAAAAAAAAAAQARIDFhkf/aAAgBAQABPyFQ1Lp9hbsrD//aAAwDAQACAAMAAAAQow//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/ED//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/ED//xAAcEAEAAgEFAAAAAAAAAAAAAAABABEhIDFBUWH/2gAIAQEAAT8QUh65DDBDYx0jC08Lej//2Q==","aspectRatio":1.7808219178082192,"src":"/static/49810f1cc6a34556c1ce36e3061364ce/d5c54/React--TanStack--Query-Tutorial-for-Beginners.jpg","srcSet":"/static/49810f1cc6a34556c1ce36e3061364ce/65d8c/React--TanStack--Query-Tutorial-for-Beginners.jpg 260w,\n/static/49810f1cc6a34556c1ce36e3061364ce/c5f21/React--TanStack--Query-Tutorial-for-Beginners.jpg 520w,\n/static/49810f1cc6a34556c1ce36e3061364ce/d5c54/React--TanStack--Query-Tutorial-for-Beginners.jpg 1040w,\n/static/49810f1cc6a34556c1ce36e3061364ce/81a53/React--TanStack--Query-Tutorial-for-Beginners.jpg 1560w","srcWebp":"/static/49810f1cc6a34556c1ce36e3061364ce/e4875/React--TanStack--Query-Tutorial-for-Beginners.webp","srcSetWebp":"/static/49810f1cc6a34556c1ce36e3061364ce/dc8f3/React--TanStack--Query-Tutorial-for-Beginners.webp 260w,\n/static/49810f1cc6a34556c1ce36e3061364ce/2db4b/React--TanStack--Query-Tutorial-for-Beginners.webp 520w,\n/static/49810f1cc6a34556c1ce36e3061364ce/e4875/React--TanStack--Query-Tutorial-for-Beginners.webp 1040w,\n/static/49810f1cc6a34556c1ce36e3061364ce/f5845/React--TanStack--Query-Tutorial-for-Beginners.webp 1560w","sizes":"(max-width: 1040px) 100vw, 1040px"}}}},"ghostPost":{"id":"Ghost__Post__62dd14674e918d05f353777d","title":"React (TanStack) Query Tutorial for Beginners","slug":"react-query-tutorial-for-beginners","featured":true,"feature_image":"https://backend.shahednasser.com/content/images/2022/07/React--TanStack--Query-Tutorial-for-Beginners.jpg","excerpt":"In this tutorial, you'll build a simple Node.js server and then learn how to interact with it on a React website using React Query.","custom_excerpt":"In this tutorial, you'll build a simple Node.js server and then learn how to interact with it on a React website using React Query.","visibility":"public","created_at_pretty":"24 Jul 2022","published_at_pretty":"24 Jul 2022","updated_at_pretty":"24 Jul 2022","created_at":"2022-07-24T09:44:07.000+00:00","published_at":"2022-07-24T15:50:35.000+00:00","updated_at":"2022-07-24T15:50:35.000+00:00","meta_title":null,"meta_description":null,"og_description":null,"og_image":null,"og_title":null,"twitter_description":null,"twitter_image":null,"twitter_title":null,"authors":[{"slug":"shahed","url":"https://backend.shahednasser.com/author/shahed/","name":"Shahed Nasser","bio":null,"cover_image":null,"profile_image":"https://backend.shahednasser.com/content/images/2022/03/IMG_0591.jpg","location":null,"website":null,"twitter":null,"facebook":null,"meta_title":null,"meta_description":null,"coverImageSharp":null,"profileImageSharp":null}],"primary_author":{"slug":"shahed","url":"https://backend.shahednasser.com/author/shahed/","name":"Shahed Nasser","bio":null,"cover_image":null,"profile_image":"https://backend.shahednasser.com/content/images/2022/03/IMG_0591.jpg","location":null,"website":null,"twitter":null,"facebook":null,"meta_title":null,"meta_description":null,"coverImageSharp":null,"profileImageSharp":{"base":"IMG_0591.jpg","publicURL":"/static/ceb49c3c631485453e71e00d7f84b069/IMG_0591.jpg","imageMeta":{"width":1182,"height":1179},"childImageSharp":{"fluid":{"base64":"data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAUABQDASIAAhEBAxEB/8QAGAABAQEBAQAAAAAAAAAAAAAAAAMEAQL/xAAWAQEBAQAAAAAAAAAAAAAAAAADBAL/2gAMAwEAAhADEAAAAdXiFM6i0CohUWXoKn//xAAcEAACAgIDAAAAAAAAAAAAAAACAwESBBEhM0H/2gAIAQEAAQUCWySE3WEr7SzbXjAj4iKty+sOQ//EABYRAQEBAAAAAAAAAAAAAAAAAAERIP/aAAgBAwEBPwEhj//EABQRAQAAAAAAAAAAAAAAAAAAACD/2gAIAQIBAT8BH//EAB4QAAIBBAMBAAAAAAAAAAAAAAABIRESMUECECJx/9oACAEBAAY/ApVGWvOjzgtUwLlTZA0sdL4f/8QAHBAAAwACAwEAAAAAAAAAAAAAAAERITFBkbHB/9oACAEBAAE/IahkCy+N2GwZpjQiJHJCspUFY0QrSi+HqiW2rgf/2gAMAwEAAgADAAAAEPw3/wD/xAAYEQEBAAMAAAAAAAAAAAAAAAAAARExQf/aAAgBAwEBPxCtjDqP/8QAFxEBAQEBAAAAAAAAAAAAAAAAAQAxEf/aAAgBAgEBPxBFus6Tt//EAB8QAQEAAgIBBQAAAAAAAAAAAAERACExQWFRcYGR0f/aAAgBAQABPxAuaBPPzkO1wyX7F4wkwXanfZrFQgeqE9JgS14vVOvrERIJomVBKwt2jebAeP0yVa8h1n//2Q==","aspectRatio":1,"src":"/static/ceb49c3c631485453e71e00d7f84b069/31709/IMG_0591.jpg","srcSet":"/static/ceb49c3c631485453e71e00d7f84b069/f340b/IMG_0591.jpg 28w,\n/static/ceb49c3c631485453e71e00d7f84b069/22d64/IMG_0591.jpg 55w,\n/static/ceb49c3c631485453e71e00d7f84b069/31709/IMG_0591.jpg 110w,\n/static/ceb49c3c631485453e71e00d7f84b069/aa249/IMG_0591.jpg 165w,\n/static/ceb49c3c631485453e71e00d7f84b069/0dc33/IMG_0591.jpg 220w,\n/static/ceb49c3c631485453e71e00d7f84b069/d8257/IMG_0591.jpg 1182w","srcWebp":"/static/ceb49c3c631485453e71e00d7f84b069/8678c/IMG_0591.webp","srcSetWebp":"/static/ceb49c3c631485453e71e00d7f84b069/59cda/IMG_0591.webp 28w,\n/static/ceb49c3c631485453e71e00d7f84b069/7da75/IMG_0591.webp 55w,\n/static/ceb49c3c631485453e71e00d7f84b069/8678c/IMG_0591.webp 110w,\n/static/ceb49c3c631485453e71e00d7f84b069/f282e/IMG_0591.webp 165w,\n/static/ceb49c3c631485453e71e00d7f84b069/a7b21/IMG_0591.webp 220w,\n/static/ceb49c3c631485453e71e00d7f84b069/63099/IMG_0591.webp 1182w","sizes":"(max-width: 110px) 100vw, 110px"}}}},"primary_tag":{"slug":"react","url":"https://backend.shahednasser.com/tag/react/","name":"React","visibility":"public","feature_image":"https://images.unsplash.com/photo-1581276879432-15e50529f34b?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=MnwxMTc3M3wwfDF8c2VhcmNofDN8fHJlYWN0fGVufDB8fHx8MTYyMjYzMzI0MA&ixlib=rb-1.2.1&q=80&w=2000","description":"Learn more about React through tutorials, articles, and tips.","meta_title":null,"meta_description":null,"featureImageSharp":{"base":"photo-1581276879432-15e50529f34b.jpg","publicURL":"/static/7140ea32e1157ba61402d5d67ab846d4/photo-1581276879432-15e50529f34b.jpg","imageMeta":{"width":2000,"height":1333},"childImageSharp":{"fluid":{"base64":"data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAANABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAIDBf/EABUBAQEAAAAAAAAAAAAAAAAAAAAB/9oADAMBAAIQAxAAAAHJai1MBP/EABcQAAMBAAAAAAAAAAAAAAAAAAABEBH/2gAIAQEAAQUCuDU//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPwE//8QAFREBAQAAAAAAAAAAAAAAAAAAEBH/2gAIAQIBAT8Bh//EABQQAQAAAAAAAAAAAAAAAAAAACD/2gAIAQEABj8CX//EABgQAQEBAQEAAAAAAAAAAAAAAAABESFR/9oACAEBAAE/IYy+rHKDH//aAAwDAQACAAMAAAAQC9//xAAVEQEBAAAAAAAAAAAAAAAAAAAQEf/aAAgBAwEBPxCn/8QAFREBAQAAAAAAAAAAAAAAAAAAARD/2gAIAQIBAT8QUT//xAAaEAADAQADAAAAAAAAAAAAAAAAAREhQWFx/9oACAEBAAE/EMY0neijzwMrrVEm7auUQPNGlP/Z","aspectRatio":1.5028901734104045,"src":"/static/7140ea32e1157ba61402d5d67ab846d4/d5c54/photo-1581276879432-15e50529f34b.jpg","srcSet":"/static/7140ea32e1157ba61402d5d67ab846d4/65d8c/photo-1581276879432-15e50529f34b.jpg 260w,\n/static/7140ea32e1157ba61402d5d67ab846d4/c5f21/photo-1581276879432-15e50529f34b.jpg 520w,\n/static/7140ea32e1157ba61402d5d67ab846d4/d5c54/photo-1581276879432-15e50529f34b.jpg 1040w,\n/static/7140ea32e1157ba61402d5d67ab846d4/81a53/photo-1581276879432-15e50529f34b.jpg 1560w,\n/static/7140ea32e1157ba61402d5d67ab846d4/4e5f3/photo-1581276879432-15e50529f34b.jpg 2000w","srcWebp":"/static/7140ea32e1157ba61402d5d67ab846d4/e4875/photo-1581276879432-15e50529f34b.webp","srcSetWebp":"/static/7140ea32e1157ba61402d5d67ab846d4/dc8f3/photo-1581276879432-15e50529f34b.webp 260w,\n/static/7140ea32e1157ba61402d5d67ab846d4/2db4b/photo-1581276879432-15e50529f34b.webp 520w,\n/static/7140ea32e1157ba61402d5d67ab846d4/e4875/photo-1581276879432-15e50529f34b.webp 1040w,\n/static/7140ea32e1157ba61402d5d67ab846d4/f5845/photo-1581276879432-15e50529f34b.webp 1560w,\n/static/7140ea32e1157ba61402d5d67ab846d4/49d6b/photo-1581276879432-15e50529f34b.webp 2000w","sizes":"(max-width: 1040px) 100vw, 1040px"}}}},"tags":[{"slug":"react","url":"https://backend.shahednasser.com/tag/react/","name":"React","visibility":"public","feature_image":"https://images.unsplash.com/photo-1581276879432-15e50529f34b?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=MnwxMTc3M3wwfDF8c2VhcmNofDN8fHJlYWN0fGVufDB8fHx8MTYyMjYzMzI0MA&ixlib=rb-1.2.1&q=80&w=2000","description":"Learn more about React through tutorials, articles, and tips.","meta_title":null,"meta_description":null,"featureImageSharp":null},{"slug":"js","url":"https://backend.shahednasser.com/tag/js/","name":"Javascript","visibility":"public","feature_image":"https://backend.shahednasser.com/content/images/2022/01/photo-1592609931095-54a2168ae893-2.jpeg","description":"Learn more about Javascript through tutorials, articles, and tips.","meta_title":null,"meta_description":"Learn more about Javascript through tutorials, articles and tips.","featureImageSharp":null}],"plaintext":"React Query (now rebranded to TanStack Query) is a React library used to make fetching and manipulating server-side data easier. Using React Query, you can implement, along with data fetching, caching, and synchronization of your data with the server.\n\nIn this tutorial, you'll build a simple Node.js server and then learn how to interact with it on a React website using React Query.\n\nPlease note that this version uses v4 of React Query which is now named TanStack Query.\n\nYou can find the code for this tutorial in this GitHub repository.\n\n\nPrerequisites\n\nBefore starting with this tutorial make sure you have Node.js installed. You need at least version 14.\n\n\nServer Setup\n\nIn this section, you'll set up a simple Node.js server with an SQLite database. The server has 3 endpoints to fetch, add, and delete notes.\n\nIf you already have a server you can skip this section and go to the Website Setup section.\n\n\nCreate Server Project\n\nCreate a new directory called server then initialize a new project using NPM:\n\nmkdir server\ncd server\nnpm init -y\n\n\nInstall Dependencies\n\nThen, install the packages you'll need for the development of the server:\n\nnpm i express cors body-parser sqlite3 nodemon\n\nHere's what each of the packages is for:\n\n 1. express to create a server using Express.\n 2. cors is an Express middleware used to handle CORS on your server.\n 3. body-parser is an Express middleware used to parse the body of a request.\n 4. sqlite3 is an SQLite database adapter for Node.js.\n 5. nodemon is a library used to restart the server whenever new changes occur to the files.\n\n\nCreate Server\n\nCreate the file index.js with the following content:\n\nconst express = require('express');\n\nconst app = express();\nconst port = 3001;\nconst cors = require('cors');\nconst sqlite3 = require('sqlite3').verbose();\nconst bodyParser = require('body-parser');\n\napp.use(bodyParser.json());\napp.use(cors());\n\napp.listen(port, () => {\n  console.log(`Notes app listening on port ${port}`);\n});\n\nThis initializes the server using Express on port 3001. It also uses the cors and body-parser middleware.\n\nThen, in package.json add a new script start to run the server:\n\n  \"scripts\": {\n    \"start\": \"nodemon index.js\"\n  },\n\n\nInitialize the Database\n\nIn index.js before app.listen add the following code:\n\nconst db = new sqlite3.Database('data.db', (err) => {\n  if (err) {\n    throw err;\n  }\n\n  // create tables if they don't exist\n  db.serialize(() => {\n    db.run(`CREATE TABLE IF NOT EXISTS notes (id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT, content TEXT, \n      created_at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP)`);\n  });\n});\n\nThis creates a new database if it doesn't exist in the file data.db. Then, if the notes table doesn't exist on the database it creates it as well.\n\n\nAdd Endpoints\n\nFollowing the database code, add the following code to add the endpoints:\n\napp.get('/notes', (req, res) => {\n  db.all('SELECT * FROM notes', (err, rows) => {\n    if (err) {\n      console.error(err);\n      return res.status(500).json({ success: false, message: 'An error occurred, please try again later' });\n    }\n\n    return res.json({ success: true, data: rows });\n  });\n});\n\napp.get('/notes/:id', (req, res) => {\n  db.get('SELECT * FROM notes WHERE id = ?', req.params.id, (err, row) => {\n    if (err) {\n      console.error(err);\n      return res.status(500).json({ success: false, message: 'An error occurred, please try again later' });\n    }\n\n    if (!row) {\n      return res.status(404).json({ success: false, message: 'Note does not exist' });\n    }\n\n    return res.json({ success: true, data: row });\n  });\n});\n\napp.post('/notes', (req, res) => {\n  const { title, content } = req.body;\n\n  if (!title || !content) {\n    return res.status(400).json({ success: false, message: 'title and content are required' });\n  }\n\n  db.run('INSERT INTO notes (title, content) VALUES (?, ?)', [title, content], function (err) {\n    if (err) {\n      console.error(err);\n      return res.status(500).json({ success: false, message: 'An error occurred, please try again later' });\n    }\n\n    return res.json({\n      success: true,\n      data: {\n        id: this.lastID,\n        title,\n        content,\n      },\n    });\n  });\n});\n\napp.delete('/notes/:id', (req, res) => {\n  const { id } = req.params;\n\n  db.get('SELECT * FROM notes WHERE id = ?', [id], (err, row) => {\n    if (err) {\n      console.error(err);\n      return res.status(500).json({ success: false, message: 'An error occurred, please try again later' });\n    }\n\n    if (!row) {\n      return res.status(404).json({ success: false, message: 'Note does not exist' });\n    }\n\n    db.run('DELETE FROM notes WHERE id = ?', [id], (error) => {\n      if (error) {\n        console.error(error);\n        return res.status(500).json({ success: false, message: 'An error occurred, please try again later' });\n      }\n\n      return res.json({ success: true, message: 'Note deleted successfully' });\n    });\n  });\n});\n\nBriefly, this creates 4 endpoints:\n\n 1. /notes endpoint of the method GET to fetch all notes.\n 2. /notes/:id endpoint of the method GET to fetch a note by an ID.\n 3. /notes endpoint of the method POST to add a note.\n 4. /notes/:id endpoint of the method DELETE to delete a note.\n\n\nTest Server\n\nRun the following command to start the server:\n\nnpm start\n\nThis starts the server on port 3001. You can test it out by sending a request to localhost:3001/notes.\n\n\nWebsite Setup\n\nIn this section, you'll create the website with Create React App (CRA). This is where you'll make use of React Query.\n\n\nCreate Website Project\n\nTo create a new React app, run the following command in a different directory:\n\nnpx create-react-app website\n\nThis creates a new React app in the directory website.\n\n\nInstall Dependencies\n\nRun the following command to change to the website directory and install the necessary dependencies for the website:\n\ncd website\nnpm i @tanstack/react-query tailwindcss postcss autoprefixer @tailwindcss/typography @heroicons/react @windmill/react-ui\n\nThe @tanstack/react-query library is the React Query library which is now named TanStack Query. The other libraries are Tailwind CSS related libraries to add styling to the website.\n\n\nTailwind CSS Setup\n\nThis section is optional and is only used to set up Tailwind CSS.\n\nCreate the file postcss.config.js with the following content:\n\nmodule.exports = {\n  plugins: {\n    tailwindcss: {},\n    autoprefixer: {},\n  },\n}\n\n\nAlso, create the file tailwind.config.js with the following content:\n\n/** @type {import('tailwindcss').Config} */\nmodule.exports = {\n  content: [\n    \"./src/**/*.{js,jsx,ts,tsx}\",\n  ],\n  theme: {\n    extend: {},\n  },\n  plugins: [\n    require('@tailwindcss/typography')\n  ],\n}\n\n\nThen, create the file src/index.css with the following content:\n\n@tailwind base;\n@tailwind components;\n@tailwind utilities;\n\nFinally, in index.js import src/index.css at the beginning of the file:\n\nimport './index.css';\n\n\nUse QueryClientProvider\n\nTo use the React Query client in all of your components, you must use it at a high level in your website's components hierarchy. The best place to put it is in src/index.js which wraps up your entire website's components.\n\nIn src/index.js add the following imports at the beginning of the file:\n\nimport {\n  QueryClient,\n  QueryClientProvider,\n} from '@tanstack/react-query'\n\nThen, initialize a new Query client:\n\nconst queryClient = new QueryClient()\n\nFinally, change the parameter passed to root.render:\n\nroot.render(\n  <QueryClientProvider client={queryClient}>\n    <App />\n  </QueryClientProvider>\n);\n\nThis wraps the App component which holds the rest of the website's components with QueryClientProvider. This provider accepts the prop client which is an instance of QueryClient.\n\nNow, all components within the website will have access to the Query Client which is used to fetch, cache, and manipulate the server data.\n\n\nImplement Display Notes\n\nFetching data from the server is an act of performing a query. Therefore, you'll use useQuery in this section.\n\nYou'll display notes in the App component. These notes are fetched from the server using the /notes endpoint.\n\nReplace the content of app.js with the following content:\n\nimport { PlusIcon, RefreshIcon } from '@heroicons/react/solid'\nimport { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'\n\nfunction App() {\n  const { isLoading, isError, data, error } = useQuery(['notes'], fetchNotes)\n\n  function fetchNotes () {\n    return fetch('http://localhost:3001/notes')\n    .then((response) => response.json())\n    .then(({ success, data }) => {\n      if (!success) {\n        throw new Error ('An error occurred while fetching notes');\n      }\n      return data;\n    })\n  }\n\n  return (\n    <div className=\"w-screen h-screen overflow-x-hidden bg-red-400 flex flex-col justify-center items-center\">\n      <div className='bg-white w-full md:w-1/2 p-5 text-center rounded shadow-md text-gray-800 prose'>\n        <h1>Notes</h1>\n        {isLoading && <RefreshIcon className=\"w-10 h-10 animate-spin mx-auto\"></RefreshIcon>}\n        {isError && <span className='text-red'>{error.message ? error.message : error}</span>}\n        {!isLoading && !isError && data && !data.length && <span className='text-red-400'>You have no notes</span>}\n        {data && data.length > 0 && data.map((note, index) => (\n          <div key={note.id} className={`text-left ${index !== data.length - 1 ? 'border-b pb-2' : ''}`}>\n            <h2>{note.title}</h2>\n            <p>{note.content}</p>\n            <span>\n              <button className='link text-gray-400'>Delete</button>\n            </span>\n          </div>\n        ))}\n      </div>\n      <button className=\"mt-2 bg-gray-700 hover:bg-gray-600 rounded-full text-white p-3\">\n        <PlusIcon className='w-5 h-5'></PlusIcon>\n      </button>\n    </div>\n  );\n}\n\nexport default App;\n\nHere's briefly what's going on in this code snippet:\n\n 1. You use useQuery to fetch the notes. The first parameter it accepts is a unique key used for caching. The second parameter is the function used to fetch the data. You pass it the fetchNotes function.\n 2. useQuery returns an object that holds many variables. Here, you use 4 of them: isLoading is a boolean value that determines whether the data is currently being fetched; isError is a boolean value that determines if an error occurred. data is the data that is fetched from the server; and error is the error message if isError is true.\n 3. The fetchNotes function must return a promise that either resolves data or throws an error. In the function, you send a GET request to localhost:3001/notes to fetch the notes. If the data is fetched successfully it is returned in the then fulfillment function.\n 4. In the returned JSX, if isLoading is true, a loading icon is shown. If isError is true, an error message is shown. If data is fetched successfully and has any data in it, the notes are rendered.\n 5. You also show a button with a plus icon to add new notes. You'll implement this later.\n\n\nTest Displaying Notes\n\nTo test out what you've implemented so far, make sure your server is still running, then start your React app server with the following command:\n\nnpm start\n\nThis runs your React app on localhost:3000 by default. If you open it in your browser, you'll see a loading icon at first then you'll see no notes as you haven't added any yet.\n\n\nImplement Add Notes Functionality\n\nAdding a note is an act of mutation on the server data. Therefore, you'll be using the useMutation hook in this section.\n\nYou'll create a separate component that shows the form used to add a note.\n\nCreate the file src/form.js with the following content:\n\nimport { useMutation, useQueryClient } from '@tanstack/react-query'\n\nimport { useState } from 'react'\n\nexport default function Form ({ isOpen, setIsOpen }) {\n  const [title, setTitle] = useState(\"\")\n  const [content, setContent] = useState(\"\")\n  const queryClient = useQueryClient()\n\n  const mutation = useMutation(insertNote, {\n    onSuccess: () => {\n      setTitle(\"\")\n      setContent(\"\")\n    }\n  })\n\n  function closeForm (e) {\n    e.preventDefault()\n    setIsOpen(false)\n  }\n\n  function insertNote () {\n    return fetch(`http://localhost:3001/notes`, {\n      method: 'POST',\n      headers: {\n        'Content-Type': 'application/json'\n      },\n      body: JSON.stringify({\n        title,\n        content\n      })\n    })\n    .then((response) => response.json())\n    .then(({ success, data }) => {\n      if (!success) {\n        throw new Error(\"An error occured\")\n      }\n      \n      setIsOpen(false)\n      queryClient.setQueriesData('notes', (old) => [...old, data])\n    })\n  }\n\n  function handleSubmit (e) {\n    e.preventDefault()\n    mutation.mutate()\n  }\n\n  return (\n    <div className={`absolute w-full h-full top-0 left-0 z-50 flex justify-center items-center ${!isOpen ? 'hidden' : ''}`}>\n      <div className='bg-black opacity-50 absolute w-full h-full top-0 left-0'></div>\n      <form className='bg-white w-full md:w-1/2 p-5 rounded shadow-md text-gray-800 prose relative' \n        onSubmit={handleSubmit}>\n        <h2 className='text-center'>Add Note</h2>\n        {mutation.isError && <span className='block mb-2 text-red-400'>{mutation.error.message ? mutation.error.message : mutation.error}</span>}\n        <input type=\"text\" placeholder='Title' className='rounded-sm w-full border px-2' \n          value={title} onChange={(e) => setTitle(e.target.value)} />\n        <textarea onChange={(e) => setContent(e.target.value)} \n          className=\"rounded-sm w-full border px-2 mt-2\" placeholder='Content' value={content}></textarea>\n        <div>\n          <button type=\"submit\" className='mt-2 bg-red-400 hover:bg-red-600 text-white p-3 rounded mr-2 disabled:pointer-events-none' \n            disabled={mutation.isLoading}>\n            Add</button>\n          <button className='mt-2 bg-gray-700 hover:bg-gray-600 text-white p-3 rounded'\n            onClick={closeForm}>Cancel</button>\n        </div>\n      </form>\n    </div>\n  )\n}\n\nHere's a brief explanation of this form\n\n 1. This form acts as a pop-up. It accepts isOpen and setIsOpen props to determine when the form is opened and handle closing it.\n 2. You use useQueryClient to get access to the Query Client. This is necessary to perform a mutation.\n 3. To handle adding a note on your server and keep all data in your query client synced, you must the useMutation hook.\n 4. The useMutation hook accepts 2 parameters. Thie first one is the function that will handle the mutation, which in this case is insertNote. The second parameter is an object of options. You pass it one option onSuccess which is a function that runs if the mutation is performed successfully. You use this to reset the title and content fields of the form.\n 5. In insertNote, you send a POST request to localhost:3001/notes and pass in the body the title and content of the note to be created. If the success body parameter returned from the server is false, an error is thrown to signal that the mutation failed.\n 6. If the note is added successfully, you change the cached value of the notes key using the queryClient.setQueriesData method. This method accepts the key as a first parameter and the new data associated with that key as a second parameter. This updates the data everywhere it's used on your website.\n 7. In this component you display a form with 2 fields: title and content. In the form, you check if an error occurs using mutation.isError and get access to the error using mutation.error.\n 8. You handle form submission in the handleSubmit function. Here, you trigger the mutation using mutation.mutate. This is where the insertNote function is triggered to add a new note.\n\nThen, in src/app.js add the following imports at the beginning of the file:\n\nimport Form from './form'\nimport { useState } from 'react'\n\nThen, at the beginning of the component add a new state variable to manage wheter the form is opened or not:\n\nconst [isOpen, setIsOpen] = useState(false)\n\nNext, add a new function addNote that just uses setIsOpen to open the form:\n\nfunction addNote () {\n    setIsOpen(true)\n}\n\nFinally, in the returned JSX, replace the button with the plus icon with the following:\n\n<button className=\"mt-2 bg-gray-700 hover:bg-gray-600 rounded-full text-white p-3\" onClick={addNote}>\n    <PlusIcon className='w-5 h-5'></PlusIcon>\n</button>\n<Form isOpen={isOpen} setIsOpen={setIsOpen} />\n\nThis sets the onClick handler of the button to addNote. It also adds the Form component you created earlier as a child component of App.\n\n\nTest Adding a Note\n\nRerun your server and React app if they're not running. Then, open the website again at localhost:3000. Click on the plus button and a pop up will open with the form to add a new note.\n\nEnter a random title and content then click Add. The pop up form will then close and you can see the new note added.\n\n\nImplement Delete Note Functionality\n\nThe last functionality you'll add is deleting notes. Deleting a note is another act of mutation as it manipulates the server's data.\n\nAt the beginning of the App component in src/app.js add the following code:\n\nconst queryClient = useQueryClient()\nconst mutation = useMutation(deleteNote, {\n    onSuccess: () => queryClient.invalidateQueries('notes')\n})\n\nHere, you get access to the query client using useQueryClient. Then, you create a new mutation using useMutation. You pass it the function deleteNote (which you'll create next) as a first parameter and an object of options.\n\nTo the onSuccess option you pass a function that does one thing. It executes the method queryClient.invalidateQueries. This method marks the cached data for a specific key as outdated, which triggers retrieving the data again.\n\nSo, once a note is deleted, the query you created earlier that executes the function fetchNotes will be triggered and the notes will be fetched again. If you had created other queries on your website that use the same key notes, they'll also be triggered to update their data.\n\nNext, add the function deleteNote in the App component in the same file:\n\nfunction deleteNote (note) {\n    return fetch(`http://localhost:3001/notes/${note.id}`, {\n      method: 'DELETE'\n    })\n    .then((response) => response.json())\n    .then(({ success, message }) => {\n      if (!success) {\n        throw new Error(message);\n      }\n\n      alert(message);\n    })\n  }\n\nThis function receives the note to be deleted as a parameter. It sends a DELETE request to localhost:3001/notes/:id. If the success body parameter of the response is false, an error is thrown. Otherwise, only an alert is shown.\n\nThen, in the returned JSX of the App component, change how the loading icon and error where shown previously to the following:\n\n{(isLoading || mutation.isLoading) && <RefreshIcon className=\"w-10 h-10 animate-spin mx-auto\"></RefreshIcon>}\n{(isError || mutation.isError) && <span className='text-red'>{error ? (error.message ? error.message : error) : mutation.error.message}</span>}\n\nThis shows the loading icon or the error message for both the query that fetches the notes and the mutation that handles deleting a note.\n\nFinally, find the delete button of a note and add an onClick handler:\n\n<button className='link text-gray-400' onClick={() => mutation.mutate(note)}>Delete</button>\n\nOn click, the mutation responsible for deleting the note is triggered using mutation.mutate. You pass it the note to delete which is the current note in a map loop.\n\n\nTest Deleting a Note\n\nRerun your server and React app if they're not running. Then, open the website again at localhost:3000. Click the Delete link for any of your notes. If the note is deleted successfully, an alert will be shown.\n\nAfter closing the alert, the notes will be fetched again and displayed, if there are any other notes.\n\n\nConclusion\n\nUsing React (TanStack) Query, you can easily handle server data fetching and manipulation on your website with advanced features such as caching and synchronization across your React app.\n\nMake sure to check out the official documentation to learn more about what you can do with React Query.","html":"<p>React Query (now rebranded to TanStack Query) is a React library used to make fetching and manipulating server-side data easier. Using React Query, you can implement, along with data fetching, caching, and synchronization of your data with the server.</p><p>In this tutorial, you'll build a simple Node.js server and then learn how to interact with it on a React website using React Query.</p><p>Please note that this version uses v4 of React Query which is now named TanStack Query.</p><p>You can find the code for this tutorial in <a href=\"https://github.com/shahednasser/react-query-tutorial\">this GitHub repository</a>.</p><h2 id=\"prerequisites\">Prerequisites</h2><p> Before starting with this tutorial make sure you have <a href=\"https://nodejs.org/en/\">Node.js installed</a>. You need at least version 14.</p><h2 id=\"server-setup\">Server Setup</h2><p>In this section, you'll set up a simple Node.js server with an SQLite database. The server has 3 endpoints to fetch, add, and delete notes.</p><p>If you already have a server you can skip this section and go to the Website Setup section.</p><h3 id=\"create-server-project\">Create Server Project</h3><p>Create a new directory called <code>server</code> then initialize a new project using NPM:</p><pre><code class=\"language-bash\">mkdir server\ncd server\nnpm init -y</code></pre><h3 id=\"install-dependencies\">Install Dependencies</h3><p>Then, install the packages you'll need for the development of the server:</p><pre><code class=\"language-bash\">npm i express cors body-parser sqlite3 nodemon</code></pre><p>Here's what each of the packages is for:</p><ol><li><code>express</code> to create a server using <a href=\"https://expressjs.com/\">Express</a>.</li><li><code>cors</code> is an Express middleware used to handle <a href=\"https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS\">CORS</a> on your server.</li><li><code>body-parser</code> is an Express middleware used to parse the body of a request.</li><li><code>sqlite3</code> is an SQLite database adapter for Node.js.</li><li><code>nodemon</code> is a library used to restart the server whenever new changes occur to the files.</li></ol><h3 id=\"create-server\">Create Server</h3><p>Create the file <code>index.js</code> with the following content:</p><pre><code class=\"language-js\">const express = require('express');\n\nconst app = express();\nconst port = 3001;\nconst cors = require('cors');\nconst sqlite3 = require('sqlite3').verbose();\nconst bodyParser = require('body-parser');\n\napp.use(bodyParser.json());\napp.use(cors());\n\napp.listen(port, () =&gt; {\n  console.log(`Notes app listening on port ${port}`);\n});</code></pre><p>This initializes the server using Express on port <code>3001</code>. It also uses the <code>cors</code> and <code>body-parser</code> middleware.</p><p>Then, in <code>package.json</code> add a new script <code>start</code> to run the server:</p><pre><code class=\"language-json\">  \"scripts\": {\n    \"start\": \"nodemon index.js\"\n  },</code></pre><h3 id=\"initialize-the-database\">Initialize the Database</h3><p>In <code>index.js</code> before <code>app.listen</code> add the following code:</p><pre><code class=\"language-js\">const db = new sqlite3.Database('data.db', (err) =&gt; {\n  if (err) {\n    throw err;\n  }\n\n  // create tables if they don't exist\n  db.serialize(() =&gt; {\n    db.run(`CREATE TABLE IF NOT EXISTS notes (id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT, content TEXT, \n      created_at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP)`);\n  });\n});</code></pre><p>This creates a new database if it doesn't exist in the file <code>data.db</code>. Then, if the <code>notes</code> table doesn't exist on the database it creates it as well.</p><h3 id=\"add-endpoints\">Add Endpoints</h3><p>Following the database code, add the following code to add the endpoints:</p><pre><code class=\"language-js\">app.get('/notes', (req, res) =&gt; {\n  db.all('SELECT * FROM notes', (err, rows) =&gt; {\n    if (err) {\n      console.error(err);\n      return res.status(500).json({ success: false, message: 'An error occurred, please try again later' });\n    }\n\n    return res.json({ success: true, data: rows });\n  });\n});\n\napp.get('/notes/:id', (req, res) =&gt; {\n  db.get('SELECT * FROM notes WHERE id = ?', req.params.id, (err, row) =&gt; {\n    if (err) {\n      console.error(err);\n      return res.status(500).json({ success: false, message: 'An error occurred, please try again later' });\n    }\n\n    if (!row) {\n      return res.status(404).json({ success: false, message: 'Note does not exist' });\n    }\n\n    return res.json({ success: true, data: row });\n  });\n});\n\napp.post('/notes', (req, res) =&gt; {\n  const { title, content } = req.body;\n\n  if (!title || !content) {\n    return res.status(400).json({ success: false, message: 'title and content are required' });\n  }\n\n  db.run('INSERT INTO notes (title, content) VALUES (?, ?)', [title, content], function (err) {\n    if (err) {\n      console.error(err);\n      return res.status(500).json({ success: false, message: 'An error occurred, please try again later' });\n    }\n\n    return res.json({\n      success: true,\n      data: {\n        id: this.lastID,\n        title,\n        content,\n      },\n    });\n  });\n});\n\napp.delete('/notes/:id', (req, res) =&gt; {\n  const { id } = req.params;\n\n  db.get('SELECT * FROM notes WHERE id = ?', [id], (err, row) =&gt; {\n    if (err) {\n      console.error(err);\n      return res.status(500).json({ success: false, message: 'An error occurred, please try again later' });\n    }\n\n    if (!row) {\n      return res.status(404).json({ success: false, message: 'Note does not exist' });\n    }\n\n    db.run('DELETE FROM notes WHERE id = ?', [id], (error) =&gt; {\n      if (error) {\n        console.error(error);\n        return res.status(500).json({ success: false, message: 'An error occurred, please try again later' });\n      }\n\n      return res.json({ success: true, message: 'Note deleted successfully' });\n    });\n  });\n});</code></pre><p>Briefly, this creates 4 endpoints:</p><ol><li><code>/notes</code> endpoint of the method <code>GET</code> to fetch all notes.</li><li><code>/notes/:id</code> endpoint of the method <code>GET</code> to fetch a note by an ID.</li><li><code>/notes</code> endpoint of the method <code>POST</code> to add a note.</li><li><code>/notes/:id</code> endpoint of the method <code>DELETE</code> to delete a note.</li></ol><h3 id=\"test-server\">Test Server</h3><p>Run the following command to start the server:</p><pre><code class=\"language-bash\">npm start</code></pre><p>This starts the server on port <code>3001</code>. You can test it out by sending a request to <code>localhost:3001/notes</code>.</p><h2 id=\"website-setup\">Website Setup</h2><p>In this section, you'll create the website with Create React App (CRA). This is where you'll make use of React Query.</p><h3 id=\"create-website-project\">Create Website Project</h3><p>To create a new React app, run the following command in a different directory:</p><pre><code class=\"language-bash\">npx create-react-app website</code></pre><p>This creates a new React app in the directory <code>website</code>.</p><h3 id=\"install-dependencies-1\">Install Dependencies</h3><p>Run the following command to change to the <code>website</code> directory and install the necessary dependencies for the website:</p><pre><code class=\"language-bash\">cd website\nnpm i @tanstack/react-query tailwindcss postcss autoprefixer @tailwindcss/typography @heroicons/react @windmill/react-ui</code></pre><p>The <code>@tanstack/react-query</code> library is the React Query library which is now named TanStack Query. The other libraries are <a href=\"https://tailwindcss.com/\">Tailwind CSS</a> related libraries to add styling to the website.</p><h3 id=\"tailwind-css-setup\">Tailwind CSS Setup</h3><p>This section is optional and is only used to set up Tailwind CSS.</p><p>Create the file <code>postcss.config.js</code> with the following content:</p><pre><code class=\"language-js\">module.exports = {\n  plugins: {\n    tailwindcss: {},\n    autoprefixer: {},\n  },\n}\n</code></pre><p>Also, create the file <code>tailwind.config.js</code> with the following content:</p><pre><code class=\"language-js\">/** @type {import('tailwindcss').Config} */\nmodule.exports = {\n  content: [\n    \"./src/**/*.{js,jsx,ts,tsx}\",\n  ],\n  theme: {\n    extend: {},\n  },\n  plugins: [\n    require('@tailwindcss/typography')\n  ],\n}\n</code></pre><p>Then, create the file <code>src/index.css</code> with the following content:</p><pre><code class=\"language-css\">@tailwind base;\n@tailwind components;\n@tailwind utilities;</code></pre><p>Finally, in <code>index.js</code> import <code>src/index.css</code> at the beginning of the file:</p><pre><code class=\"language-js\">import './index.css';</code></pre><h3 id=\"use-queryclientprovider\">Use QueryClientProvider</h3><p>To use the React Query client in all of your components, you must use it at a high level in your website's components hierarchy. The best place to put it is in <code>src/index.js</code> which wraps up your entire website's components.</p><p>In <code>src/index.js</code> add the following imports at the beginning of the file:</p><pre><code class=\"language-js\">import {\n  QueryClient,\n  QueryClientProvider,\n} from '@tanstack/react-query'</code></pre><p>Then, initialize a new Query client:</p><pre><code class=\"language-js\">const queryClient = new QueryClient()</code></pre><p>Finally, change the parameter passed to <code>root.render</code>:</p><pre><code class=\"language-js\">root.render(\n  &lt;QueryClientProvider client={queryClient}&gt;\n    &lt;App /&gt;\n  &lt;/QueryClientProvider&gt;\n);</code></pre><p>This wraps the <code>App</code> component which holds the rest of the website's components with <code>QueryClientProvider</code>. This provider accepts the prop <code>client</code> which is an instance of <code>QueryClient</code>.</p><p>Now, all components within the website will have access to the Query Client which is used to fetch, cache, and manipulate the server data.</p><h3 id=\"implement-display-notes\">Implement Display Notes</h3><p>Fetching data from the server is an act of performing a query. Therefore, you'll use <code>useQuery</code> in this section.</p><p>You'll display notes in the <code>App</code> component. These notes are fetched from the server using the <code>/notes</code> endpoint.</p><p>Replace the content of <code>app.js</code> with the following content:</p><pre><code class=\"language-js\">import { PlusIcon, RefreshIcon } from '@heroicons/react/solid'\nimport { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'\n\nfunction App() {\n  const { isLoading, isError, data, error } = useQuery(['notes'], fetchNotes)\n\n  function fetchNotes () {\n    return fetch('http://localhost:3001/notes')\n    .then((response) =&gt; response.json())\n    .then(({ success, data }) =&gt; {\n      if (!success) {\n        throw new Error ('An error occurred while fetching notes');\n      }\n      return data;\n    })\n  }\n\n  return (\n    &lt;div className=\"w-screen h-screen overflow-x-hidden bg-red-400 flex flex-col justify-center items-center\"&gt;\n      &lt;div className='bg-white w-full md:w-1/2 p-5 text-center rounded shadow-md text-gray-800 prose'&gt;\n        &lt;h1&gt;Notes&lt;/h1&gt;\n        {isLoading &amp;&amp; &lt;RefreshIcon className=\"w-10 h-10 animate-spin mx-auto\"&gt;&lt;/RefreshIcon&gt;}\n        {isError &amp;&amp; &lt;span className='text-red'&gt;{error.message ? error.message : error}&lt;/span&gt;}\n        {!isLoading &amp;&amp; !isError &amp;&amp; data &amp;&amp; !data.length &amp;&amp; &lt;span className='text-red-400'&gt;You have no notes&lt;/span&gt;}\n        {data &amp;&amp; data.length &gt; 0 &amp;&amp; data.map((note, index) =&gt; (\n          &lt;div key={note.id} className={`text-left ${index !== data.length - 1 ? 'border-b pb-2' : ''}`}&gt;\n            &lt;h2&gt;{note.title}&lt;/h2&gt;\n            &lt;p&gt;{note.content}&lt;/p&gt;\n            &lt;span&gt;\n              &lt;button className='link text-gray-400'&gt;Delete&lt;/button&gt;\n            &lt;/span&gt;\n          &lt;/div&gt;\n        ))}\n      &lt;/div&gt;\n      &lt;button className=\"mt-2 bg-gray-700 hover:bg-gray-600 rounded-full text-white p-3\"&gt;\n        &lt;PlusIcon className='w-5 h-5'&gt;&lt;/PlusIcon&gt;\n      &lt;/button&gt;\n    &lt;/div&gt;\n  );\n}\n\nexport default App;</code></pre><p>Here's briefly what's going on in this code snippet:</p><ol><li>You use <code>useQuery</code> to fetch the notes. The first parameter it accepts is a unique key used for caching. The second parameter is the function used to fetch the data. You pass it the <code>fetchNotes</code> function.</li><li><code>useQuery</code> returns an object that holds <a href=\"https://tanstack.com/query/v4/docs/reference/useQuery\">many variables</a>. Here, you use 4 of them: <code>isLoading</code> is a boolean value that determines whether the data is currently being fetched; <code>isError</code> is a boolean value that determines if an error occurred. <code>data</code> is the data that is fetched from the server; and <code>error</code> is the error message if <code>isError</code> is true.</li><li>The <code>fetchNotes</code> function must return a promise that either resolves data or throws an error. In the function, you send a <code>GET</code> request to <code>localhost:3001/notes</code> to fetch the notes. If the data is fetched successfully it is returned in the <code>then</code> fulfillment function. </li><li>In the returned JSX, if <code>isLoading</code> is true, a loading icon is shown. If <code>isError</code> is true, an error message is shown. If <code>data</code> is fetched successfully and has any data in it, the notes are rendered.</li><li>You also show a button with a plus icon to add new notes. You'll implement this later.</li></ol><h3 id=\"test-displaying-notes\">Test Displaying Notes</h3><p>To test out what you've implemented so far, make sure your server is still running, then start your React app server with the following command:</p><pre><code class=\"language-bash\">npm start</code></pre><p>This runs your React app on <code>localhost:3000</code> by default. If you open it in your browser, you'll see a loading icon at first then you'll see no notes as you haven't added any yet.</p><figure class=\"kg-card kg-image-card\"><img src=\"https://backend.shahednasser.com/content/images/2022/07/Screen-Shot-2022-06-28-at-9.10.04-PM.png\" class=\"kg-image\" alt loading=\"lazy\" width=\"1446\" height=\"490\" srcset=\"https://backend.shahednasser.com/content/images/size/w600/2022/07/Screen-Shot-2022-06-28-at-9.10.04-PM.png 600w, https://backend.shahednasser.com/content/images/size/w1000/2022/07/Screen-Shot-2022-06-28-at-9.10.04-PM.png 1000w, https://backend.shahednasser.com/content/images/2022/07/Screen-Shot-2022-06-28-at-9.10.04-PM.png 1446w\" sizes=\"(min-width: 720px) 720px\"></figure><h3 id=\"implement-add-notes-functionality\">Implement Add Notes Functionality</h3><p>Adding a note is an act of mutation on the server data. Therefore, you'll be using the <code>useMutation</code> hook in this section.</p><p>You'll create a separate component that shows the form used to add a note.</p><p>Create the file <code>src/form.js</code> with the following content:</p><pre><code class=\"language-js\">import { useMutation, useQueryClient } from '@tanstack/react-query'\n\nimport { useState } from 'react'\n\nexport default function Form ({ isOpen, setIsOpen }) {\n  const [title, setTitle] = useState(\"\")\n  const [content, setContent] = useState(\"\")\n  const queryClient = useQueryClient()\n\n  const mutation = useMutation(insertNote, {\n    onSuccess: () =&gt; {\n      setTitle(\"\")\n      setContent(\"\")\n    }\n  })\n\n  function closeForm (e) {\n    e.preventDefault()\n    setIsOpen(false)\n  }\n\n  function insertNote () {\n    return fetch(`http://localhost:3001/notes`, {\n      method: 'POST',\n      headers: {\n        'Content-Type': 'application/json'\n      },\n      body: JSON.stringify({\n        title,\n        content\n      })\n    })\n    .then((response) =&gt; response.json())\n    .then(({ success, data }) =&gt; {\n      if (!success) {\n        throw new Error(\"An error occured\")\n      }\n      \n      setIsOpen(false)\n      queryClient.setQueriesData('notes', (old) =&gt; [...old, data])\n    })\n  }\n\n  function handleSubmit (e) {\n    e.preventDefault()\n    mutation.mutate()\n  }\n\n  return (\n    &lt;div className={`absolute w-full h-full top-0 left-0 z-50 flex justify-center items-center ${!isOpen ? 'hidden' : ''}`}&gt;\n      &lt;div className='bg-black opacity-50 absolute w-full h-full top-0 left-0'&gt;&lt;/div&gt;\n      &lt;form className='bg-white w-full md:w-1/2 p-5 rounded shadow-md text-gray-800 prose relative' \n        onSubmit={handleSubmit}&gt;\n        &lt;h2 className='text-center'&gt;Add Note&lt;/h2&gt;\n        {mutation.isError &amp;&amp; &lt;span className='block mb-2 text-red-400'&gt;{mutation.error.message ? mutation.error.message : mutation.error}&lt;/span&gt;}\n        &lt;input type=\"text\" placeholder='Title' className='rounded-sm w-full border px-2' \n          value={title} onChange={(e) =&gt; setTitle(e.target.value)} /&gt;\n        &lt;textarea onChange={(e) =&gt; setContent(e.target.value)} \n          className=\"rounded-sm w-full border px-2 mt-2\" placeholder='Content' value={content}&gt;&lt;/textarea&gt;\n        &lt;div&gt;\n          &lt;button type=\"submit\" className='mt-2 bg-red-400 hover:bg-red-600 text-white p-3 rounded mr-2 disabled:pointer-events-none' \n            disabled={mutation.isLoading}&gt;\n            Add&lt;/button&gt;\n          &lt;button className='mt-2 bg-gray-700 hover:bg-gray-600 text-white p-3 rounded'\n            onClick={closeForm}&gt;Cancel&lt;/button&gt;\n        &lt;/div&gt;\n      &lt;/form&gt;\n    &lt;/div&gt;\n  )\n}</code></pre><p>Here's a brief explanation of this form</p><ol><li>This form acts as a pop-up. It accepts <code>isOpen</code> and <code>setIsOpen</code> props to determine when the form is opened and handle closing it.</li><li>You use <code>useQueryClient</code> to get access to the Query Client. This is necessary to perform a mutation.</li><li>To handle adding a note on your server and keep all data in your query client synced, you must the <code>useMutation</code> hook. </li><li>The <code>useMutation</code> hook accepts 2 parameters. Thie first one is the function that will handle the mutation, which in this case is <code>insertNote</code>. The second parameter is an object of <a href=\"https://tanstack.com/query/v4/docs/reference/useMutation\">options</a>. You pass it one option <code>onSuccess</code> which is a function that runs if the mutation is performed successfully. You use this to reset the <code>title</code> and <code>content</code> fields of the form.</li><li>In <code>insertNote</code>, you send a <code>POST</code> request to <code>localhost:3001/notes</code> and pass in the body the <code>title</code> and <code>content</code> of the note to be created. If the <code>success</code> body parameter returned from the server is <code>false</code>, an error is thrown to signal that the mutation failed. </li><li>If the note is added successfully, you change the cached value of the <code>notes</code> key using the <code>queryClient.setQueriesData</code> method. This method accepts the key as a first parameter and the new data associated with that key as a second parameter. This updates the data everywhere it's used on your website.</li><li>In this component you display a form with 2 fields: <code>title</code> and <code>content</code>. In the form, you check if an error occurs using <code>mutation.isError</code> and get access to the error using <code>mutation.error</code>.</li><li>You handle form submission in the <code>handleSubmit</code> function. Here, you trigger the mutation using <code>mutation.mutate</code>. This is where the <code>insertNote</code> function is triggered to add a new note.</li></ol><p>Then, in <code>src/app.js</code> add the following imports at the beginning of the file:</p><pre><code class=\"language-js\">import Form from './form'\nimport { useState } from 'react'</code></pre><p>Then, at the beginning of the component add a new state variable to manage wheter the form is opened or not:</p><pre><code class=\"language-js\">const [isOpen, setIsOpen] = useState(false)</code></pre><p>Next, add a new function <code>addNote</code> that just uses <code>setIsOpen</code> to open the form:</p><pre><code class=\"language-js\">function addNote () {\n    setIsOpen(true)\n}</code></pre><p>Finally, in the returned JSX, replace the button with the plus icon with the following:</p><pre><code class=\"language-js\">&lt;button className=\"mt-2 bg-gray-700 hover:bg-gray-600 rounded-full text-white p-3\" onClick={addNote}&gt;\n    &lt;PlusIcon className='w-5 h-5'&gt;&lt;/PlusIcon&gt;\n&lt;/button&gt;\n&lt;Form isOpen={isOpen} setIsOpen={setIsOpen} /&gt;</code></pre><p>This sets the <code>onClick</code> handler of the button to <code>addNote</code>. It also adds the <code>Form</code> component you created earlier as a child component of <code>App</code>. </p><h3 id=\"test-adding-a-note\">Test Adding a Note</h3><p>Rerun your server and React app if they're not running. Then, open the website again at <code>localhost:3000</code>. Click on the plus button and a pop up will open with the form to add a new note.</p><figure class=\"kg-card kg-image-card\"><img src=\"https://backend.shahednasser.com/content/images/2022/07/Screen-Shot-2022-07-24-at-6.31.41-PM.png\" class=\"kg-image\" alt loading=\"lazy\" width=\"1494\" height=\"792\" srcset=\"https://backend.shahednasser.com/content/images/size/w600/2022/07/Screen-Shot-2022-07-24-at-6.31.41-PM.png 600w, https://backend.shahednasser.com/content/images/size/w1000/2022/07/Screen-Shot-2022-07-24-at-6.31.41-PM.png 1000w, https://backend.shahednasser.com/content/images/2022/07/Screen-Shot-2022-07-24-at-6.31.41-PM.png 1494w\" sizes=\"(min-width: 720px) 720px\"></figure><p>Enter a random title and content then click Add. The pop up form will then close and you can see the new note added.</p><figure class=\"kg-card kg-image-card\"><img src=\"https://backend.shahednasser.com/content/images/2022/07/Screen-Shot-2022-07-24-at-6.32.53-PM.png\" class=\"kg-image\" alt loading=\"lazy\" width=\"1418\" height=\"720\" srcset=\"https://backend.shahednasser.com/content/images/size/w600/2022/07/Screen-Shot-2022-07-24-at-6.32.53-PM.png 600w, https://backend.shahednasser.com/content/images/size/w1000/2022/07/Screen-Shot-2022-07-24-at-6.32.53-PM.png 1000w, https://backend.shahednasser.com/content/images/2022/07/Screen-Shot-2022-07-24-at-6.32.53-PM.png 1418w\" sizes=\"(min-width: 720px) 720px\"></figure><h3 id=\"implement-delete-note-functionality\">Implement Delete Note Functionality</h3><p>The last functionality you'll add is deleting notes. Deleting a note is another act of mutation as it manipulates the server's data.</p><p>At the beginning of the <code>App</code> component in <code>src/app.js</code> add the following code:</p><pre><code class=\"language-js\">const queryClient = useQueryClient()\nconst mutation = useMutation(deleteNote, {\n    onSuccess: () =&gt; queryClient.invalidateQueries('notes')\n})</code></pre><p>Here, you get access to the query client using <code>useQueryClient</code>. Then, you create a new mutation using <code>useMutation</code>. You pass it the function <code>deleteNote</code> (which you'll create next) as a first parameter and an object of options. </p><p>To the <code>onSuccess</code> option you pass a function that does one thing. It executes the method <code>queryClient.invalidateQueries</code>. This method marks the cached data for a specific key as outdated, which triggers retrieving the data again. </p><p>So, once a note is deleted, the query you created earlier that executes the function <code>fetchNotes</code> will be triggered and the notes will be fetched again. If you had created other queries on your website that use the same key <code>notes</code>, they'll also be triggered to update their data. </p><p>Next, add the function <code>deleteNote</code> in the <code>App</code> component in the same file:</p><pre><code class=\"language-js\">function deleteNote (note) {\n    return fetch(`http://localhost:3001/notes/${note.id}`, {\n      method: 'DELETE'\n    })\n    .then((response) =&gt; response.json())\n    .then(({ success, message }) =&gt; {\n      if (!success) {\n        throw new Error(message);\n      }\n\n      alert(message);\n    })\n  }</code></pre><p>This function receives the <code>note</code> to be deleted as a parameter. It sends a <code>DELETE</code> request to <code>localhost:3001/notes/:id</code>. If the <code>success</code> body parameter of the response is <code>false</code>, an error is thrown. Otherwise, only an alert is shown.</p><p>Then, in the returned JSX of the <code>App</code> component, change how the loading icon and error where shown previously to the following:</p><pre><code class=\"language-js\">{(isLoading || mutation.isLoading) &amp;&amp; &lt;RefreshIcon className=\"w-10 h-10 animate-spin mx-auto\"&gt;&lt;/RefreshIcon&gt;}\n{(isError || mutation.isError) &amp;&amp; &lt;span className='text-red'&gt;{error ? (error.message ? error.message : error) : mutation.error.message}&lt;/span&gt;}</code></pre><p>This shows the loading icon or the error message for both the query that fetches the notes and the mutation that handles deleting a note.</p><p>Finally, find the delete button of a note and add an <code>onClick</code> handler:</p><pre><code class=\"language-js\">&lt;button className='link text-gray-400' onClick={() =&gt; mutation.mutate(note)}&gt;Delete&lt;/button&gt;</code></pre><p>On click, the mutation responsible for deleting the note is triggered using <code>mutation.mutate</code>. You pass it the note to delete which is the current note in a <code>map</code> loop.</p><h3 id=\"test-deleting-a-note\">Test Deleting a Note</h3><p>Rerun your server and React app if they're not running. Then, open the website again at <code>localhost:3000</code>. Click the Delete link for any of your notes. If the note is deleted successfully, an alert will be shown.</p><figure class=\"kg-card kg-image-card\"><img src=\"https://backend.shahednasser.com/content/images/2022/07/Screen-Shot-2022-07-01-at-2.48.53-PM.png\" class=\"kg-image\" alt loading=\"lazy\" width=\"1006\" height=\"314\" srcset=\"https://backend.shahednasser.com/content/images/size/w600/2022/07/Screen-Shot-2022-07-01-at-2.48.53-PM.png 600w, https://backend.shahednasser.com/content/images/size/w1000/2022/07/Screen-Shot-2022-07-01-at-2.48.53-PM.png 1000w, https://backend.shahednasser.com/content/images/2022/07/Screen-Shot-2022-07-01-at-2.48.53-PM.png 1006w\" sizes=\"(min-width: 720px) 720px\"></figure><p>After closing the alert, the notes will be fetched again and displayed, if there are any other notes.</p><figure class=\"kg-card kg-image-card\"><img src=\"https://backend.shahednasser.com/content/images/2022/07/Screen-Shot-2022-06-28-at-9.10.04-PM-1.png\" class=\"kg-image\" alt loading=\"lazy\" width=\"1446\" height=\"490\" srcset=\"https://backend.shahednasser.com/content/images/size/w600/2022/07/Screen-Shot-2022-06-28-at-9.10.04-PM-1.png 600w, https://backend.shahednasser.com/content/images/size/w1000/2022/07/Screen-Shot-2022-06-28-at-9.10.04-PM-1.png 1000w, https://backend.shahednasser.com/content/images/2022/07/Screen-Shot-2022-06-28-at-9.10.04-PM-1.png 1446w\" sizes=\"(min-width: 720px) 720px\"></figure><h2 id=\"conclusion\">Conclusion</h2><p>Using React (TanStack) Query, you can easily handle server data fetching and manipulation on your website with advanced features such as caching and synchronization across your React app.</p><p>Make sure to check out the <a href=\"https://tanstack.com/query/v4\">official documentation</a> to learn more about what you can do with React Query.</p>","url":"https://backend.shahednasser.com/react-query-tutorial-for-beginners/","canonical_url":null,"uuid":"59ed8cc6-4d4d-4eac-a4c7-5bfd0118df23","codeinjection_foot":null,"codeinjection_head":null,"codeinjection_styles":null,"comment_id":"62dd14674e918d05f353777d","reading_time":13,"send_email_when_published":null,"email_subject":null,"childHtmlRehype":{"html":"<p>React Query (now rebranded to TanStack Query) is a React library used to make fetching and manipulating server-side data easier. Using React Query, you can implement, along with data fetching, caching, and synchronization of your data with the server.</p><p>In this tutorial, you'll build a simple Node.js server and then learn how to interact with it on a React website using React Query.</p><p>Please note that this version uses v4 of React Query which is now named TanStack Query.</p><p>You can find the code for this tutorial in <a href=\"https://github.com/shahednasser/react-query-tutorial\">this GitHub repository</a>.</p><h2 id=\"prerequisites\">Prerequisites</h2><p> Before starting with this tutorial make sure you have <a href=\"https://nodejs.org/en/\">Node.js installed</a>. You need at least version 14.</p><h2 id=\"server-setup\">Server Setup</h2><p>In this section, you'll set up a simple Node.js server with an SQLite database. The server has 3 endpoints to fetch, add, and delete notes.</p><p>If you already have a server you can skip this section and go to the Website Setup section.</p><h3 id=\"create-server-project\">Create Server Project</h3><p>Create a new directory called <code class=\"language-text\">server</code> then initialize a new project using NPM:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\"><span class=\"token function\">mkdir</span> server\n<span class=\"token builtin class-name\">cd</span> server\n<span class=\"token function\">npm</span> init -y</code></pre></div><h3 id=\"install-dependencies\">Install Dependencies</h3><p>Then, install the packages you'll need for the development of the server:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\"><span class=\"token function\">npm</span> i express cors body-parser sqlite3 nodemon</code></pre></div><p>Here's what each of the packages is for:</p><ol><li><code class=\"language-text\">express</code> to create a server using <a href=\"https://expressjs.com/\">Express</a>.</li><li><code class=\"language-text\">cors</code> is an Express middleware used to handle <a href=\"https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS\">CORS</a> on your server.</li><li><code class=\"language-text\">body-parser</code> is an Express middleware used to parse the body of a request.</li><li><code class=\"language-text\">sqlite3</code> is an SQLite database adapter for Node.js.</li><li><code class=\"language-text\">nodemon</code> is a library used to restart the server whenever new changes occur to the files.</li></ol><h3 id=\"create-server\">Create Server</h3><p>Create the file <code class=\"language-text\">index.js</code> with the following content:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">const</span> express <span class=\"token operator\">=</span> <span class=\"token function\">require</span><span class=\"token punctuation\">(</span><span class=\"token string\">'express'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token keyword\">const</span> app <span class=\"token operator\">=</span> <span class=\"token function\">express</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">const</span> port <span class=\"token operator\">=</span> <span class=\"token number\">3001</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">const</span> cors <span class=\"token operator\">=</span> <span class=\"token function\">require</span><span class=\"token punctuation\">(</span><span class=\"token string\">'cors'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">const</span> sqlite3 <span class=\"token operator\">=</span> <span class=\"token function\">require</span><span class=\"token punctuation\">(</span><span class=\"token string\">'sqlite3'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">verbose</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">const</span> bodyParser <span class=\"token operator\">=</span> <span class=\"token function\">require</span><span class=\"token punctuation\">(</span><span class=\"token string\">'body-parser'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\napp<span class=\"token punctuation\">.</span><span class=\"token function\">use</span><span class=\"token punctuation\">(</span>bodyParser<span class=\"token punctuation\">.</span><span class=\"token function\">json</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\napp<span class=\"token punctuation\">.</span><span class=\"token function\">use</span><span class=\"token punctuation\">(</span><span class=\"token function\">cors</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\napp<span class=\"token punctuation\">.</span><span class=\"token function\">listen</span><span class=\"token punctuation\">(</span>port<span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  console<span class=\"token punctuation\">.</span><span class=\"token function\">log</span><span class=\"token punctuation\">(</span><span class=\"token template-string\"><span class=\"token template-punctuation string\">`</span><span class=\"token string\">Notes app listening on port </span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${</span>port<span class=\"token interpolation-punctuation punctuation\">}</span></span><span class=\"token template-punctuation string\">`</span></span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div><p>This initializes the server using Express on port <code class=\"language-text\">3001</code>. It also uses the <code class=\"language-text\">cors</code> and <code class=\"language-text\">body-parser</code> middleware.</p><p>Then, in <code class=\"language-text\">package.json</code> add a new script <code class=\"language-text\">start</code> to run the server:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"json\"><pre class=\"language-json\"><code class=\"language-json\">  <span class=\"token property\">\"scripts\"</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token property\">\"start\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"nodemon index.js\"</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span></code></pre></div><h3 id=\"initialize-the-database\">Initialize the Database</h3><p>In <code class=\"language-text\">index.js</code> before <code class=\"language-text\">app.listen</code> add the following code:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">const</span> db <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">sqlite3<span class=\"token punctuation\">.</span>Database</span><span class=\"token punctuation\">(</span><span class=\"token string\">'data.db'</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">err</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>err<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">throw</span> err<span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n\n  <span class=\"token comment\">// create tables if they don't exist</span>\n  db<span class=\"token punctuation\">.</span><span class=\"token function\">serialize</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    db<span class=\"token punctuation\">.</span><span class=\"token function\">run</span><span class=\"token punctuation\">(</span><span class=\"token template-string\"><span class=\"token template-punctuation string\">`</span><span class=\"token string\">CREATE TABLE IF NOT EXISTS notes (id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT, content TEXT, \n      created_at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP)</span><span class=\"token template-punctuation string\">`</span></span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div><p>This creates a new database if it doesn't exist in the file <code class=\"language-text\">data.db</code>. Then, if the <code class=\"language-text\">notes</code> table doesn't exist on the database it creates it as well.</p><h3 id=\"add-endpoints\">Add Endpoints</h3><p>Following the database code, add the following code to add the endpoints:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\">app<span class=\"token punctuation\">.</span><span class=\"token function\">get</span><span class=\"token punctuation\">(</span><span class=\"token string\">'/notes'</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">req<span class=\"token punctuation\">,</span> res</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  db<span class=\"token punctuation\">.</span><span class=\"token function\">all</span><span class=\"token punctuation\">(</span><span class=\"token string\">'SELECT * FROM notes'</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">err<span class=\"token punctuation\">,</span> rows</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>err<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n      console<span class=\"token punctuation\">.</span><span class=\"token function\">error</span><span class=\"token punctuation\">(</span>err<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n      <span class=\"token keyword\">return</span> res<span class=\"token punctuation\">.</span><span class=\"token function\">status</span><span class=\"token punctuation\">(</span><span class=\"token number\">500</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">json</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">success</span><span class=\"token operator\">:</span> <span class=\"token boolean\">false</span><span class=\"token punctuation\">,</span> <span class=\"token literal-property property\">message</span><span class=\"token operator\">:</span> <span class=\"token string\">'An error occurred, please try again later'</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token keyword\">return</span> res<span class=\"token punctuation\">.</span><span class=\"token function\">json</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">success</span><span class=\"token operator\">:</span> <span class=\"token boolean\">true</span><span class=\"token punctuation\">,</span> <span class=\"token literal-property property\">data</span><span class=\"token operator\">:</span> rows <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\napp<span class=\"token punctuation\">.</span><span class=\"token function\">get</span><span class=\"token punctuation\">(</span><span class=\"token string\">'/notes/:id'</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">req<span class=\"token punctuation\">,</span> res</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  db<span class=\"token punctuation\">.</span><span class=\"token function\">get</span><span class=\"token punctuation\">(</span><span class=\"token string\">'SELECT * FROM notes WHERE id = ?'</span><span class=\"token punctuation\">,</span> req<span class=\"token punctuation\">.</span>params<span class=\"token punctuation\">.</span>id<span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">err<span class=\"token punctuation\">,</span> row</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>err<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n      console<span class=\"token punctuation\">.</span><span class=\"token function\">error</span><span class=\"token punctuation\">(</span>err<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n      <span class=\"token keyword\">return</span> res<span class=\"token punctuation\">.</span><span class=\"token function\">status</span><span class=\"token punctuation\">(</span><span class=\"token number\">500</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">json</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">success</span><span class=\"token operator\">:</span> <span class=\"token boolean\">false</span><span class=\"token punctuation\">,</span> <span class=\"token literal-property property\">message</span><span class=\"token operator\">:</span> <span class=\"token string\">'An error occurred, please try again later'</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">!</span>row<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n      <span class=\"token keyword\">return</span> res<span class=\"token punctuation\">.</span><span class=\"token function\">status</span><span class=\"token punctuation\">(</span><span class=\"token number\">404</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">json</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">success</span><span class=\"token operator\">:</span> <span class=\"token boolean\">false</span><span class=\"token punctuation\">,</span> <span class=\"token literal-property property\">message</span><span class=\"token operator\">:</span> <span class=\"token string\">'Note does not exist'</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token keyword\">return</span> res<span class=\"token punctuation\">.</span><span class=\"token function\">json</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">success</span><span class=\"token operator\">:</span> <span class=\"token boolean\">true</span><span class=\"token punctuation\">,</span> <span class=\"token literal-property property\">data</span><span class=\"token operator\">:</span> row <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\napp<span class=\"token punctuation\">.</span><span class=\"token function\">post</span><span class=\"token punctuation\">(</span><span class=\"token string\">'/notes'</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">req<span class=\"token punctuation\">,</span> res</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">const</span> <span class=\"token punctuation\">{</span> title<span class=\"token punctuation\">,</span> content <span class=\"token punctuation\">}</span> <span class=\"token operator\">=</span> req<span class=\"token punctuation\">.</span>body<span class=\"token punctuation\">;</span>\n\n  <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">!</span>title <span class=\"token operator\">||</span> <span class=\"token operator\">!</span>content<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">return</span> res<span class=\"token punctuation\">.</span><span class=\"token function\">status</span><span class=\"token punctuation\">(</span><span class=\"token number\">400</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">json</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">success</span><span class=\"token operator\">:</span> <span class=\"token boolean\">false</span><span class=\"token punctuation\">,</span> <span class=\"token literal-property property\">message</span><span class=\"token operator\">:</span> <span class=\"token string\">'title and content are required'</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n\n  db<span class=\"token punctuation\">.</span><span class=\"token function\">run</span><span class=\"token punctuation\">(</span><span class=\"token string\">'INSERT INTO notes (title, content) VALUES (?, ?)'</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">[</span>title<span class=\"token punctuation\">,</span> content<span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> <span class=\"token keyword\">function</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">err</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>err<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n      console<span class=\"token punctuation\">.</span><span class=\"token function\">error</span><span class=\"token punctuation\">(</span>err<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n      <span class=\"token keyword\">return</span> res<span class=\"token punctuation\">.</span><span class=\"token function\">status</span><span class=\"token punctuation\">(</span><span class=\"token number\">500</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">json</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">success</span><span class=\"token operator\">:</span> <span class=\"token boolean\">false</span><span class=\"token punctuation\">,</span> <span class=\"token literal-property property\">message</span><span class=\"token operator\">:</span> <span class=\"token string\">'An error occurred, please try again later'</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token keyword\">return</span> res<span class=\"token punctuation\">.</span><span class=\"token function\">json</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>\n      <span class=\"token literal-property property\">success</span><span class=\"token operator\">:</span> <span class=\"token boolean\">true</span><span class=\"token punctuation\">,</span>\n      <span class=\"token literal-property property\">data</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token literal-property property\">id</span><span class=\"token operator\">:</span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>lastID<span class=\"token punctuation\">,</span>\n        title<span class=\"token punctuation\">,</span>\n        content<span class=\"token punctuation\">,</span>\n      <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\napp<span class=\"token punctuation\">.</span><span class=\"token function\">delete</span><span class=\"token punctuation\">(</span><span class=\"token string\">'/notes/:id'</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">req<span class=\"token punctuation\">,</span> res</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">const</span> <span class=\"token punctuation\">{</span> id <span class=\"token punctuation\">}</span> <span class=\"token operator\">=</span> req<span class=\"token punctuation\">.</span>params<span class=\"token punctuation\">;</span>\n\n  db<span class=\"token punctuation\">.</span><span class=\"token function\">get</span><span class=\"token punctuation\">(</span><span class=\"token string\">'SELECT * FROM notes WHERE id = ?'</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">[</span>id<span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">err<span class=\"token punctuation\">,</span> row</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>err<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n      console<span class=\"token punctuation\">.</span><span class=\"token function\">error</span><span class=\"token punctuation\">(</span>err<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n      <span class=\"token keyword\">return</span> res<span class=\"token punctuation\">.</span><span class=\"token function\">status</span><span class=\"token punctuation\">(</span><span class=\"token number\">500</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">json</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">success</span><span class=\"token operator\">:</span> <span class=\"token boolean\">false</span><span class=\"token punctuation\">,</span> <span class=\"token literal-property property\">message</span><span class=\"token operator\">:</span> <span class=\"token string\">'An error occurred, please try again later'</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">!</span>row<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n      <span class=\"token keyword\">return</span> res<span class=\"token punctuation\">.</span><span class=\"token function\">status</span><span class=\"token punctuation\">(</span><span class=\"token number\">404</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">json</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">success</span><span class=\"token operator\">:</span> <span class=\"token boolean\">false</span><span class=\"token punctuation\">,</span> <span class=\"token literal-property property\">message</span><span class=\"token operator\">:</span> <span class=\"token string\">'Note does not exist'</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n\n    db<span class=\"token punctuation\">.</span><span class=\"token function\">run</span><span class=\"token punctuation\">(</span><span class=\"token string\">'DELETE FROM notes WHERE id = ?'</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">[</span>id<span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">error</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n      <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>error<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        console<span class=\"token punctuation\">.</span><span class=\"token function\">error</span><span class=\"token punctuation\">(</span>error<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token keyword\">return</span> res<span class=\"token punctuation\">.</span><span class=\"token function\">status</span><span class=\"token punctuation\">(</span><span class=\"token number\">500</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">json</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">success</span><span class=\"token operator\">:</span> <span class=\"token boolean\">false</span><span class=\"token punctuation\">,</span> <span class=\"token literal-property property\">message</span><span class=\"token operator\">:</span> <span class=\"token string\">'An error occurred, please try again later'</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n      <span class=\"token punctuation\">}</span>\n\n      <span class=\"token keyword\">return</span> res<span class=\"token punctuation\">.</span><span class=\"token function\">json</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> <span class=\"token literal-property property\">success</span><span class=\"token operator\">:</span> <span class=\"token boolean\">true</span><span class=\"token punctuation\">,</span> <span class=\"token literal-property property\">message</span><span class=\"token operator\">:</span> <span class=\"token string\">'Note deleted successfully'</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div><p>Briefly, this creates 4 endpoints:</p><ol><li><code class=\"language-text\">/notes</code> endpoint of the method <code class=\"language-text\">GET</code> to fetch all notes.</li><li><code class=\"language-text\">/notes/:id</code> endpoint of the method <code class=\"language-text\">GET</code> to fetch a note by an ID.</li><li><code class=\"language-text\">/notes</code> endpoint of the method <code class=\"language-text\">POST</code> to add a note.</li><li><code class=\"language-text\">/notes/:id</code> endpoint of the method <code class=\"language-text\">DELETE</code> to delete a note.</li></ol><h3 id=\"test-server\">Test Server</h3><p>Run the following command to start the server:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\"><span class=\"token function\">npm</span> start</code></pre></div><p>This starts the server on port <code class=\"language-text\">3001</code>. You can test it out by sending a request to <code class=\"language-text\">localhost:3001/notes</code>.</p><h2 id=\"website-setup\">Website Setup</h2><p>In this section, you'll create the website with Create React App (CRA). This is where you'll make use of React Query.</p><h3 id=\"create-website-project\">Create Website Project</h3><p>To create a new React app, run the following command in a different directory:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">npx create-react-app website</code></pre></div><p>This creates a new React app in the directory <code class=\"language-text\">website</code>.</p><h3 id=\"install-dependencies-1\">Install Dependencies</h3><p>Run the following command to change to the <code class=\"language-text\">website</code> directory and install the necessary dependencies for the website:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\"><span class=\"token builtin class-name\">cd</span> website\n<span class=\"token function\">npm</span> i @tanstack/react-query tailwindcss postcss autoprefixer @tailwindcss/typography @heroicons/react @windmill/react-ui</code></pre></div><p>The <code class=\"language-text\">@tanstack/react-query</code> library is the React Query library which is now named TanStack Query. The other libraries are <a href=\"https://tailwindcss.com/\">Tailwind CSS</a> related libraries to add styling to the website.</p><h3 id=\"tailwind-css-setup\">Tailwind CSS Setup</h3><p>This section is optional and is only used to set up Tailwind CSS.</p><p>Create the file <code class=\"language-text\">postcss.config.js</code> with the following content:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\">module<span class=\"token punctuation\">.</span>exports <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token literal-property property\">plugins</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token literal-property property\">tailwindcss</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span><span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n    <span class=\"token literal-property property\">autoprefixer</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span><span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n<span class=\"token punctuation\">}</span>\n</code></pre></div><p>Also, create the file <code class=\"language-text\">tailwind.config.js</code> with the following content:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token comment\">/** @type {import('tailwindcss').Config} */</span>\nmodule<span class=\"token punctuation\">.</span>exports <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token literal-property property\">content</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">[</span>\n    <span class=\"token string\">\"./src/**/*.{js,jsx,ts,tsx}\"</span><span class=\"token punctuation\">,</span>\n  <span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span>\n  <span class=\"token literal-property property\">theme</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token literal-property property\">extend</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span><span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n  <span class=\"token literal-property property\">plugins</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">[</span>\n    <span class=\"token function\">require</span><span class=\"token punctuation\">(</span><span class=\"token string\">'@tailwindcss/typography'</span><span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span>\n<span class=\"token punctuation\">}</span>\n</code></pre></div><p>Then, create the file <code class=\"language-text\">src/index.css</code> with the following content:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"css\"><pre class=\"language-css\"><code class=\"language-css\"><span class=\"token atrule\"><span class=\"token rule\">@tailwind</span> base<span class=\"token punctuation\">;</span></span>\n<span class=\"token atrule\"><span class=\"token rule\">@tailwind</span> components<span class=\"token punctuation\">;</span></span>\n<span class=\"token atrule\"><span class=\"token rule\">@tailwind</span> utilities<span class=\"token punctuation\">;</span></span></code></pre></div><p>Finally, in <code class=\"language-text\">index.js</code> import <code class=\"language-text\">src/index.css</code> at the beginning of the file:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">import</span> <span class=\"token string\">'./index.css'</span><span class=\"token punctuation\">;</span></code></pre></div><h3 id=\"use-queryclientprovider\">Use QueryClientProvider</h3><p>To use the React Query client in all of your components, you must use it at a high level in your website's components hierarchy. The best place to put it is in <code class=\"language-text\">src/index.js</code> which wraps up your entire website's components.</p><p>In <code class=\"language-text\">src/index.js</code> add the following imports at the beginning of the file:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span>\n  QueryClient<span class=\"token punctuation\">,</span>\n  QueryClientProvider<span class=\"token punctuation\">,</span>\n<span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'@tanstack/react-query'</span></code></pre></div><p>Then, initialize a new Query client:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">const</span> queryClient <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">QueryClient</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></code></pre></div><p>Finally, change the parameter passed to <code class=\"language-text\">root.render</code>:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\">root<span class=\"token punctuation\">.</span><span class=\"token function\">render</span><span class=\"token punctuation\">(</span>\n  <span class=\"token operator\">&#x3C;</span>QueryClientProvider client<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span>queryClient<span class=\"token punctuation\">}</span><span class=\"token operator\">></span>\n    <span class=\"token operator\">&#x3C;</span>App <span class=\"token operator\">/</span><span class=\"token operator\">></span>\n  <span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>QueryClientProvider<span class=\"token operator\">></span>\n<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div><p>This wraps the <code class=\"language-text\">App</code> component which holds the rest of the website's components with <code class=\"language-text\">QueryClientProvider</code>. This provider accepts the prop <code class=\"language-text\">client</code> which is an instance of <code class=\"language-text\">QueryClient</code>.</p><p>Now, all components within the website will have access to the Query Client which is used to fetch, cache, and manipulate the server data.</p><h3 id=\"implement-display-notes\">Implement Display Notes</h3><p>Fetching data from the server is an act of performing a query. Therefore, you'll use <code class=\"language-text\">useQuery</code> in this section.</p><p>You'll display notes in the <code class=\"language-text\">App</code> component. These notes are fetched from the server using the <code class=\"language-text\">/notes</code> endpoint.</p><p>Replace the content of <code class=\"language-text\">app.js</code> with the following content:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span> PlusIcon<span class=\"token punctuation\">,</span> RefreshIcon <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'@heroicons/react/solid'</span>\n<span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span> useMutation<span class=\"token punctuation\">,</span> useQuery<span class=\"token punctuation\">,</span> useQueryClient <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'@tanstack/react-query'</span>\n\n<span class=\"token keyword\">function</span> <span class=\"token function\">App</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">const</span> <span class=\"token punctuation\">{</span> isLoading<span class=\"token punctuation\">,</span> isError<span class=\"token punctuation\">,</span> data<span class=\"token punctuation\">,</span> error <span class=\"token punctuation\">}</span> <span class=\"token operator\">=</span> <span class=\"token function\">useQuery</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">[</span><span class=\"token string\">'notes'</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> fetchNotes<span class=\"token punctuation\">)</span>\n\n  <span class=\"token keyword\">function</span> <span class=\"token function\">fetchNotes</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">return</span> <span class=\"token function\">fetch</span><span class=\"token punctuation\">(</span><span class=\"token string\">'http://localhost:3001/notes'</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">.</span><span class=\"token function\">then</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">response</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> response<span class=\"token punctuation\">.</span><span class=\"token function\">json</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">.</span><span class=\"token function\">then</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token parameter\"><span class=\"token punctuation\">{</span> success<span class=\"token punctuation\">,</span> data <span class=\"token punctuation\">}</span></span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n      <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">!</span>success<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">throw</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Error</span> <span class=\"token punctuation\">(</span><span class=\"token string\">'An error occurred while fetching notes'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n      <span class=\"token punctuation\">}</span>\n      <span class=\"token keyword\">return</span> data<span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">}</span>\n\n  <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span>\n    <span class=\"token operator\">&#x3C;</span>div className<span class=\"token operator\">=</span><span class=\"token string\">\"w-screen h-screen overflow-x-hidden bg-red-400 flex flex-col justify-center items-center\"</span><span class=\"token operator\">></span>\n      <span class=\"token operator\">&#x3C;</span>div className<span class=\"token operator\">=</span><span class=\"token string\">'bg-white w-full md:w-1/2 p-5 text-center rounded shadow-md text-gray-800 prose'</span><span class=\"token operator\">></span>\n        <span class=\"token operator\">&#x3C;</span>h1<span class=\"token operator\">></span>Notes<span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>h1<span class=\"token operator\">></span>\n        <span class=\"token punctuation\">{</span>isLoading <span class=\"token operator\">&#x26;&#x26;</span> <span class=\"token operator\">&#x3C;</span>RefreshIcon className<span class=\"token operator\">=</span><span class=\"token string\">\"w-10 h-10 animate-spin mx-auto\"</span><span class=\"token operator\">></span><span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>RefreshIcon<span class=\"token operator\">></span><span class=\"token punctuation\">}</span>\n        <span class=\"token punctuation\">{</span>isError <span class=\"token operator\">&#x26;&#x26;</span> <span class=\"token operator\">&#x3C;</span>span className<span class=\"token operator\">=</span><span class=\"token string\">'text-red'</span><span class=\"token operator\">></span><span class=\"token punctuation\">{</span>error<span class=\"token punctuation\">.</span>message <span class=\"token operator\">?</span> error<span class=\"token punctuation\">.</span>message <span class=\"token operator\">:</span> error<span class=\"token punctuation\">}</span><span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>span<span class=\"token operator\">></span><span class=\"token punctuation\">}</span>\n        <span class=\"token punctuation\">{</span><span class=\"token operator\">!</span>isLoading <span class=\"token operator\">&#x26;&#x26;</span> <span class=\"token operator\">!</span>isError <span class=\"token operator\">&#x26;&#x26;</span> data <span class=\"token operator\">&#x26;&#x26;</span> <span class=\"token operator\">!</span>data<span class=\"token punctuation\">.</span>length <span class=\"token operator\">&#x26;&#x26;</span> <span class=\"token operator\">&#x3C;</span>span className<span class=\"token operator\">=</span><span class=\"token string\">'text-red-400'</span><span class=\"token operator\">></span>You have no notes<span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>span<span class=\"token operator\">></span><span class=\"token punctuation\">}</span>\n        <span class=\"token punctuation\">{</span>data <span class=\"token operator\">&#x26;&#x26;</span> data<span class=\"token punctuation\">.</span>length <span class=\"token operator\">></span> <span class=\"token number\">0</span> <span class=\"token operator\">&#x26;&#x26;</span> data<span class=\"token punctuation\">.</span><span class=\"token function\">map</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">note<span class=\"token punctuation\">,</span> index</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">(</span>\n          <span class=\"token operator\">&#x3C;</span>div key<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span>note<span class=\"token punctuation\">.</span>id<span class=\"token punctuation\">}</span> className<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span><span class=\"token template-string\"><span class=\"token template-punctuation string\">`</span><span class=\"token string\">text-left </span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${</span>index <span class=\"token operator\">!==</span> data<span class=\"token punctuation\">.</span>length <span class=\"token operator\">-</span> <span class=\"token number\">1</span> <span class=\"token operator\">?</span> <span class=\"token string\">'border-b pb-2'</span> <span class=\"token operator\">:</span> <span class=\"token string\">''</span><span class=\"token interpolation-punctuation punctuation\">}</span></span><span class=\"token template-punctuation string\">`</span></span><span class=\"token punctuation\">}</span><span class=\"token operator\">></span>\n            <span class=\"token operator\">&#x3C;</span>h2<span class=\"token operator\">></span><span class=\"token punctuation\">{</span>note<span class=\"token punctuation\">.</span>title<span class=\"token punctuation\">}</span><span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>h2<span class=\"token operator\">></span>\n            <span class=\"token operator\">&#x3C;</span>p<span class=\"token operator\">></span><span class=\"token punctuation\">{</span>note<span class=\"token punctuation\">.</span>content<span class=\"token punctuation\">}</span><span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>p<span class=\"token operator\">></span>\n            <span class=\"token operator\">&#x3C;</span>span<span class=\"token operator\">></span>\n              <span class=\"token operator\">&#x3C;</span>button className<span class=\"token operator\">=</span><span class=\"token string\">'link text-gray-400'</span><span class=\"token operator\">></span>Delete<span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>button<span class=\"token operator\">></span>\n            <span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>span<span class=\"token operator\">></span>\n          <span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>div<span class=\"token operator\">></span>\n        <span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">}</span>\n      <span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>div<span class=\"token operator\">></span>\n      <span class=\"token operator\">&#x3C;</span>button className<span class=\"token operator\">=</span><span class=\"token string\">\"mt-2 bg-gray-700 hover:bg-gray-600 rounded-full text-white p-3\"</span><span class=\"token operator\">></span>\n        <span class=\"token operator\">&#x3C;</span>PlusIcon className<span class=\"token operator\">=</span><span class=\"token string\">'w-5 h-5'</span><span class=\"token operator\">></span><span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>PlusIcon<span class=\"token operator\">></span>\n      <span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>button<span class=\"token operator\">></span>\n    <span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>div<span class=\"token operator\">></span>\n  <span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">export</span> <span class=\"token keyword\">default</span> App<span class=\"token punctuation\">;</span></code></pre></div><p>Here's briefly what's going on in this code snippet:</p><ol><li>You use <code class=\"language-text\">useQuery</code> to fetch the notes. The first parameter it accepts is a unique key used for caching. The second parameter is the function used to fetch the data. You pass it the <code class=\"language-text\">fetchNotes</code> function.</li><li><code class=\"language-text\">useQuery</code> returns an object that holds <a href=\"https://tanstack.com/query/v4/docs/reference/useQuery\">many variables</a>. Here, you use 4 of them: <code class=\"language-text\">isLoading</code> is a boolean value that determines whether the data is currently being fetched; <code class=\"language-text\">isError</code> is a boolean value that determines if an error occurred. <code class=\"language-text\">data</code> is the data that is fetched from the server; and <code class=\"language-text\">error</code> is the error message if <code class=\"language-text\">isError</code> is true.</li><li>The <code class=\"language-text\">fetchNotes</code> function must return a promise that either resolves data or throws an error. In the function, you send a <code class=\"language-text\">GET</code> request to <code class=\"language-text\">localhost:3001/notes</code> to fetch the notes. If the data is fetched successfully it is returned in the <code class=\"language-text\">then</code> fulfillment function. </li><li>In the returned JSX, if <code class=\"language-text\">isLoading</code> is true, a loading icon is shown. If <code class=\"language-text\">isError</code> is true, an error message is shown. If <code class=\"language-text\">data</code> is fetched successfully and has any data in it, the notes are rendered.</li><li>You also show a button with a plus icon to add new notes. You'll implement this later.</li></ol><h3 id=\"test-displaying-notes\">Test Displaying Notes</h3><p>To test out what you've implemented so far, make sure your server is still running, then start your React app server with the following command:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\"><span class=\"token function\">npm</span> start</code></pre></div><p>This runs your React app on <code class=\"language-text\">localhost:3000</code> by default. If you open it in your browser, you'll see a loading icon at first then you'll see no notes as you haven't added any yet.</p><figure class=\"kg-card kg-image-card\"><img src=\"https://backend.shahednasser.com/content/images/2022/07/Screen-Shot-2022-06-28-at-9.10.04-PM.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"1446\" height=\"490\" srcset=\"https://backend.shahednasser.com/content/images/size/w600/2022/07/Screen-Shot-2022-06-28-at-9.10.04-PM.png 600w, https://backend.shahednasser.com/content/images/size/w1000/2022/07/Screen-Shot-2022-06-28-at-9.10.04-PM.png 1000w, https://backend.shahednasser.com/content/images/2022/07/Screen-Shot-2022-06-28-at-9.10.04-PM.png 1446w\" sizes=\"(min-width: 720px) 720px\"></figure><h3 id=\"implement-add-notes-functionality\">Implement Add Notes Functionality</h3><p>Adding a note is an act of mutation on the server data. Therefore, you'll be using the <code class=\"language-text\">useMutation</code> hook in this section.</p><p>You'll create a separate component that shows the form used to add a note.</p><p>Create the file <code class=\"language-text\">src/form.js</code> with the following content:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span> useMutation<span class=\"token punctuation\">,</span> useQueryClient <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'@tanstack/react-query'</span>\n\n<span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span> useState <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'react'</span>\n\n<span class=\"token keyword\">export</span> <span class=\"token keyword\">default</span> <span class=\"token keyword\">function</span> <span class=\"token function\">Form</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\"><span class=\"token punctuation\">{</span> isOpen<span class=\"token punctuation\">,</span> setIsOpen <span class=\"token punctuation\">}</span></span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">const</span> <span class=\"token punctuation\">[</span>title<span class=\"token punctuation\">,</span> setTitle<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token function\">useState</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"\"</span><span class=\"token punctuation\">)</span>\n  <span class=\"token keyword\">const</span> <span class=\"token punctuation\">[</span>content<span class=\"token punctuation\">,</span> setContent<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token function\">useState</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"\"</span><span class=\"token punctuation\">)</span>\n  <span class=\"token keyword\">const</span> queryClient <span class=\"token operator\">=</span> <span class=\"token function\">useQueryClient</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n\n  <span class=\"token keyword\">const</span> mutation <span class=\"token operator\">=</span> <span class=\"token function\">useMutation</span><span class=\"token punctuation\">(</span>insertNote<span class=\"token punctuation\">,</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token function-variable function\">onSuccess</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n      <span class=\"token function\">setTitle</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"\"</span><span class=\"token punctuation\">)</span>\n      <span class=\"token function\">setContent</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"\"</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n\n  <span class=\"token keyword\">function</span> <span class=\"token function\">closeForm</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">e</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    e<span class=\"token punctuation\">.</span><span class=\"token function\">preventDefault</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    <span class=\"token function\">setIsOpen</span><span class=\"token punctuation\">(</span><span class=\"token boolean\">false</span><span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">}</span>\n\n  <span class=\"token keyword\">function</span> <span class=\"token function\">insertNote</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">return</span> <span class=\"token function\">fetch</span><span class=\"token punctuation\">(</span><span class=\"token template-string\"><span class=\"token template-punctuation string\">`</span><span class=\"token string\">http://localhost:3001/notes</span><span class=\"token template-punctuation string\">`</span></span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">{</span>\n      <span class=\"token literal-property property\">method</span><span class=\"token operator\">:</span> <span class=\"token string\">'POST'</span><span class=\"token punctuation\">,</span>\n      <span class=\"token literal-property property\">headers</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token string-property property\">'Content-Type'</span><span class=\"token operator\">:</span> <span class=\"token string\">'application/json'</span>\n      <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n      <span class=\"token literal-property property\">body</span><span class=\"token operator\">:</span> <span class=\"token constant\">JSON</span><span class=\"token punctuation\">.</span><span class=\"token function\">stringify</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>\n        title<span class=\"token punctuation\">,</span>\n        content\n      <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">.</span><span class=\"token function\">then</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">response</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> response<span class=\"token punctuation\">.</span><span class=\"token function\">json</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">.</span><span class=\"token function\">then</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token parameter\"><span class=\"token punctuation\">{</span> success<span class=\"token punctuation\">,</span> data <span class=\"token punctuation\">}</span></span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n      <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">!</span>success<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">throw</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Error</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"An error occured\"</span><span class=\"token punctuation\">)</span>\n      <span class=\"token punctuation\">}</span>\n      \n      <span class=\"token function\">setIsOpen</span><span class=\"token punctuation\">(</span><span class=\"token boolean\">false</span><span class=\"token punctuation\">)</span>\n      queryClient<span class=\"token punctuation\">.</span><span class=\"token function\">setQueriesData</span><span class=\"token punctuation\">(</span><span class=\"token string\">'notes'</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">old</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">[</span><span class=\"token operator\">...</span>old<span class=\"token punctuation\">,</span> data<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">}</span>\n\n  <span class=\"token keyword\">function</span> <span class=\"token function\">handleSubmit</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">e</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    e<span class=\"token punctuation\">.</span><span class=\"token function\">preventDefault</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    mutation<span class=\"token punctuation\">.</span><span class=\"token function\">mutate</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">}</span>\n\n  <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span>\n    <span class=\"token operator\">&#x3C;</span>div className<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span><span class=\"token template-string\"><span class=\"token template-punctuation string\">`</span><span class=\"token string\">absolute w-full h-full top-0 left-0 z-50 flex justify-center items-center </span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${</span><span class=\"token operator\">!</span>isOpen <span class=\"token operator\">?</span> <span class=\"token string\">'hidden'</span> <span class=\"token operator\">:</span> <span class=\"token string\">''</span><span class=\"token interpolation-punctuation punctuation\">}</span></span><span class=\"token template-punctuation string\">`</span></span><span class=\"token punctuation\">}</span><span class=\"token operator\">></span>\n      <span class=\"token operator\">&#x3C;</span>div className<span class=\"token operator\">=</span><span class=\"token string\">'bg-black opacity-50 absolute w-full h-full top-0 left-0'</span><span class=\"token operator\">></span><span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>div<span class=\"token operator\">></span>\n      <span class=\"token operator\">&#x3C;</span>form className<span class=\"token operator\">=</span><span class=\"token string\">'bg-white w-full md:w-1/2 p-5 rounded shadow-md text-gray-800 prose relative'</span> \n        onSubmit<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span>handleSubmit<span class=\"token punctuation\">}</span><span class=\"token operator\">></span>\n        <span class=\"token operator\">&#x3C;</span>h2 className<span class=\"token operator\">=</span><span class=\"token string\">'text-center'</span><span class=\"token operator\">></span>Add Note<span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>h2<span class=\"token operator\">></span>\n        <span class=\"token punctuation\">{</span>mutation<span class=\"token punctuation\">.</span>isError <span class=\"token operator\">&#x26;&#x26;</span> <span class=\"token operator\">&#x3C;</span>span className<span class=\"token operator\">=</span><span class=\"token string\">'block mb-2 text-red-400'</span><span class=\"token operator\">></span><span class=\"token punctuation\">{</span>mutation<span class=\"token punctuation\">.</span>error<span class=\"token punctuation\">.</span>message <span class=\"token operator\">?</span> mutation<span class=\"token punctuation\">.</span>error<span class=\"token punctuation\">.</span>message <span class=\"token operator\">:</span> mutation<span class=\"token punctuation\">.</span>error<span class=\"token punctuation\">}</span><span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>span<span class=\"token operator\">></span><span class=\"token punctuation\">}</span>\n        <span class=\"token operator\">&#x3C;</span>input type<span class=\"token operator\">=</span><span class=\"token string\">\"text\"</span> placeholder<span class=\"token operator\">=</span><span class=\"token string\">'Title'</span> className<span class=\"token operator\">=</span><span class=\"token string\">'rounded-sm w-full border px-2'</span> \n          value<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span>title<span class=\"token punctuation\">}</span> onChange<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">e</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token function\">setTitle</span><span class=\"token punctuation\">(</span>e<span class=\"token punctuation\">.</span>target<span class=\"token punctuation\">.</span>value<span class=\"token punctuation\">)</span><span class=\"token punctuation\">}</span> <span class=\"token operator\">/</span><span class=\"token operator\">></span>\n        <span class=\"token operator\">&#x3C;</span>textarea onChange<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">e</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token function\">setContent</span><span class=\"token punctuation\">(</span>e<span class=\"token punctuation\">.</span>target<span class=\"token punctuation\">.</span>value<span class=\"token punctuation\">)</span><span class=\"token punctuation\">}</span> \n          className<span class=\"token operator\">=</span><span class=\"token string\">\"rounded-sm w-full border px-2 mt-2\"</span> placeholder<span class=\"token operator\">=</span><span class=\"token string\">'Content'</span> value<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span>content<span class=\"token punctuation\">}</span><span class=\"token operator\">></span><span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>textarea<span class=\"token operator\">></span>\n        <span class=\"token operator\">&#x3C;</span>div<span class=\"token operator\">></span>\n          <span class=\"token operator\">&#x3C;</span>button type<span class=\"token operator\">=</span><span class=\"token string\">\"submit\"</span> className<span class=\"token operator\">=</span><span class=\"token string\">'mt-2 bg-red-400 hover:bg-red-600 text-white p-3 rounded mr-2 disabled:pointer-events-none'</span> \n            disabled<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span>mutation<span class=\"token punctuation\">.</span>isLoading<span class=\"token punctuation\">}</span><span class=\"token operator\">></span>\n            Add<span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>button<span class=\"token operator\">></span>\n          <span class=\"token operator\">&#x3C;</span>button className<span class=\"token operator\">=</span><span class=\"token string\">'mt-2 bg-gray-700 hover:bg-gray-600 text-white p-3 rounded'</span>\n            onClick<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span>closeForm<span class=\"token punctuation\">}</span><span class=\"token operator\">></span>Cancel<span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>button<span class=\"token operator\">></span>\n        <span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>div<span class=\"token operator\">></span>\n      <span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>form<span class=\"token operator\">></span>\n    <span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>div<span class=\"token operator\">></span>\n  <span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span></code></pre></div><p>Here's a brief explanation of this form</p><ol><li>This form acts as a pop-up. It accepts <code class=\"language-text\">isOpen</code> and <code class=\"language-text\">setIsOpen</code> props to determine when the form is opened and handle closing it.</li><li>You use <code class=\"language-text\">useQueryClient</code> to get access to the Query Client. This is necessary to perform a mutation.</li><li>To handle adding a note on your server and keep all data in your query client synced, you must the <code class=\"language-text\">useMutation</code> hook. </li><li>The <code class=\"language-text\">useMutation</code> hook accepts 2 parameters. Thie first one is the function that will handle the mutation, which in this case is <code class=\"language-text\">insertNote</code>. The second parameter is an object of <a href=\"https://tanstack.com/query/v4/docs/reference/useMutation\">options</a>. You pass it one option <code class=\"language-text\">onSuccess</code> which is a function that runs if the mutation is performed successfully. You use this to reset the <code class=\"language-text\">title</code> and <code class=\"language-text\">content</code> fields of the form.</li><li>In <code class=\"language-text\">insertNote</code>, you send a <code class=\"language-text\">POST</code> request to <code class=\"language-text\">localhost:3001/notes</code> and pass in the body the <code class=\"language-text\">title</code> and <code class=\"language-text\">content</code> of the note to be created. If the <code class=\"language-text\">success</code> body parameter returned from the server is <code class=\"language-text\">false</code>, an error is thrown to signal that the mutation failed. </li><li>If the note is added successfully, you change the cached value of the <code class=\"language-text\">notes</code> key using the <code class=\"language-text\">queryClient.setQueriesData</code> method. This method accepts the key as a first parameter and the new data associated with that key as a second parameter. This updates the data everywhere it's used on your website.</li><li>In this component you display a form with 2 fields: <code class=\"language-text\">title</code> and <code class=\"language-text\">content</code>. In the form, you check if an error occurs using <code class=\"language-text\">mutation.isError</code> and get access to the error using <code class=\"language-text\">mutation.error</code>.</li><li>You handle form submission in the <code class=\"language-text\">handleSubmit</code> function. Here, you trigger the mutation using <code class=\"language-text\">mutation.mutate</code>. This is where the <code class=\"language-text\">insertNote</code> function is triggered to add a new note.</li></ol><p>Then, in <code class=\"language-text\">src/app.js</code> add the following imports at the beginning of the file:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">import</span> Form <span class=\"token keyword\">from</span> <span class=\"token string\">'./form'</span>\n<span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span> useState <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'react'</span></code></pre></div><p>Then, at the beginning of the component add a new state variable to manage wheter the form is opened or not:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">const</span> <span class=\"token punctuation\">[</span>isOpen<span class=\"token punctuation\">,</span> setIsOpen<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token function\">useState</span><span class=\"token punctuation\">(</span><span class=\"token boolean\">false</span><span class=\"token punctuation\">)</span></code></pre></div><p>Next, add a new function <code class=\"language-text\">addNote</code> that just uses <code class=\"language-text\">setIsOpen</code> to open the form:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">function</span> <span class=\"token function\">addNote</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token function\">setIsOpen</span><span class=\"token punctuation\">(</span><span class=\"token boolean\">true</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span></code></pre></div><p>Finally, in the returned JSX, replace the button with the plus icon with the following:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token operator\">&#x3C;</span>button className<span class=\"token operator\">=</span><span class=\"token string\">\"mt-2 bg-gray-700 hover:bg-gray-600 rounded-full text-white p-3\"</span> onClick<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span>addNote<span class=\"token punctuation\">}</span><span class=\"token operator\">></span>\n    <span class=\"token operator\">&#x3C;</span>PlusIcon className<span class=\"token operator\">=</span><span class=\"token string\">'w-5 h-5'</span><span class=\"token operator\">></span><span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>PlusIcon<span class=\"token operator\">></span>\n<span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>button<span class=\"token operator\">></span>\n<span class=\"token operator\">&#x3C;</span>Form isOpen<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span>isOpen<span class=\"token punctuation\">}</span> setIsOpen<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span>setIsOpen<span class=\"token punctuation\">}</span> <span class=\"token operator\">/</span><span class=\"token operator\">></span></code></pre></div><p>This sets the <code class=\"language-text\">onClick</code> handler of the button to <code class=\"language-text\">addNote</code>. It also adds the <code class=\"language-text\">Form</code> component you created earlier as a child component of <code class=\"language-text\">App</code>. </p><h3 id=\"test-adding-a-note\">Test Adding a Note</h3><p>Rerun your server and React app if they're not running. Then, open the website again at <code class=\"language-text\">localhost:3000</code>. Click on the plus button and a pop up will open with the form to add a new note.</p><figure class=\"kg-card kg-image-card\"><img src=\"https://backend.shahednasser.com/content/images/2022/07/Screen-Shot-2022-07-24-at-6.31.41-PM.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"1494\" height=\"792\" srcset=\"https://backend.shahednasser.com/content/images/size/w600/2022/07/Screen-Shot-2022-07-24-at-6.31.41-PM.png 600w, https://backend.shahednasser.com/content/images/size/w1000/2022/07/Screen-Shot-2022-07-24-at-6.31.41-PM.png 1000w, https://backend.shahednasser.com/content/images/2022/07/Screen-Shot-2022-07-24-at-6.31.41-PM.png 1494w\" sizes=\"(min-width: 720px) 720px\"></figure><p>Enter a random title and content then click Add. The pop up form will then close and you can see the new note added.</p><figure class=\"kg-card kg-image-card\"><img src=\"https://backend.shahednasser.com/content/images/2022/07/Screen-Shot-2022-07-24-at-6.32.53-PM.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"1418\" height=\"720\" srcset=\"https://backend.shahednasser.com/content/images/size/w600/2022/07/Screen-Shot-2022-07-24-at-6.32.53-PM.png 600w, https://backend.shahednasser.com/content/images/size/w1000/2022/07/Screen-Shot-2022-07-24-at-6.32.53-PM.png 1000w, https://backend.shahednasser.com/content/images/2022/07/Screen-Shot-2022-07-24-at-6.32.53-PM.png 1418w\" sizes=\"(min-width: 720px) 720px\"></figure><h3 id=\"implement-delete-note-functionality\">Implement Delete Note Functionality</h3><p>The last functionality you'll add is deleting notes. Deleting a note is another act of mutation as it manipulates the server's data.</p><p>At the beginning of the <code class=\"language-text\">App</code> component in <code class=\"language-text\">src/app.js</code> add the following code:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">const</span> queryClient <span class=\"token operator\">=</span> <span class=\"token function\">useQueryClient</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n<span class=\"token keyword\">const</span> mutation <span class=\"token operator\">=</span> <span class=\"token function\">useMutation</span><span class=\"token punctuation\">(</span>deleteNote<span class=\"token punctuation\">,</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token function-variable function\">onSuccess</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> queryClient<span class=\"token punctuation\">.</span><span class=\"token function\">invalidateQueries</span><span class=\"token punctuation\">(</span><span class=\"token string\">'notes'</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span></code></pre></div><p>Here, you get access to the query client using <code class=\"language-text\">useQueryClient</code>. Then, you create a new mutation using <code class=\"language-text\">useMutation</code>. You pass it the function <code class=\"language-text\">deleteNote</code> (which you'll create next) as a first parameter and an object of options. </p><p>To the <code class=\"language-text\">onSuccess</code> option you pass a function that does one thing. It executes the method <code class=\"language-text\">queryClient.invalidateQueries</code>. This method marks the cached data for a specific key as outdated, which triggers retrieving the data again. </p><p>So, once a note is deleted, the query you created earlier that executes the function <code class=\"language-text\">fetchNotes</code> will be triggered and the notes will be fetched again. If you had created other queries on your website that use the same key <code class=\"language-text\">notes</code>, they'll also be triggered to update their data. </p><p>Next, add the function <code class=\"language-text\">deleteNote</code> in the <code class=\"language-text\">App</code> component in the same file:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">function</span> <span class=\"token function\">deleteNote</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">note</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">return</span> <span class=\"token function\">fetch</span><span class=\"token punctuation\">(</span><span class=\"token template-string\"><span class=\"token template-punctuation string\">`</span><span class=\"token string\">http://localhost:3001/notes/</span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${</span>note<span class=\"token punctuation\">.</span>id<span class=\"token interpolation-punctuation punctuation\">}</span></span><span class=\"token template-punctuation string\">`</span></span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">{</span>\n      <span class=\"token literal-property property\">method</span><span class=\"token operator\">:</span> <span class=\"token string\">'DELETE'</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">.</span><span class=\"token function\">then</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">response</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> response<span class=\"token punctuation\">.</span><span class=\"token function\">json</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">.</span><span class=\"token function\">then</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token parameter\"><span class=\"token punctuation\">{</span> success<span class=\"token punctuation\">,</span> message <span class=\"token punctuation\">}</span></span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n      <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">!</span>success<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">throw</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Error</span><span class=\"token punctuation\">(</span>message<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n      <span class=\"token punctuation\">}</span>\n\n      <span class=\"token function\">alert</span><span class=\"token punctuation\">(</span>message<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">}</span></code></pre></div><p>This function receives the <code class=\"language-text\">note</code> to be deleted as a parameter. It sends a <code class=\"language-text\">DELETE</code> request to <code class=\"language-text\">localhost:3001/notes/:id</code>. If the <code class=\"language-text\">success</code> body parameter of the response is <code class=\"language-text\">false</code>, an error is thrown. Otherwise, only an alert is shown.</p><p>Then, in the returned JSX of the <code class=\"language-text\">App</code> component, change how the loading icon and error where shown previously to the following:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token punctuation\">{</span><span class=\"token punctuation\">(</span>isLoading <span class=\"token operator\">||</span> mutation<span class=\"token punctuation\">.</span>isLoading<span class=\"token punctuation\">)</span> <span class=\"token operator\">&#x26;&#x26;</span> <span class=\"token operator\">&#x3C;</span>RefreshIcon className<span class=\"token operator\">=</span><span class=\"token string\">\"w-10 h-10 animate-spin mx-auto\"</span><span class=\"token operator\">></span><span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>RefreshIcon<span class=\"token operator\">></span><span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">{</span><span class=\"token punctuation\">(</span>isError <span class=\"token operator\">||</span> mutation<span class=\"token punctuation\">.</span>isError<span class=\"token punctuation\">)</span> <span class=\"token operator\">&#x26;&#x26;</span> <span class=\"token operator\">&#x3C;</span>span className<span class=\"token operator\">=</span><span class=\"token string\">'text-red'</span><span class=\"token operator\">></span><span class=\"token punctuation\">{</span>error <span class=\"token operator\">?</span> <span class=\"token punctuation\">(</span>error<span class=\"token punctuation\">.</span>message <span class=\"token operator\">?</span> error<span class=\"token punctuation\">.</span>message <span class=\"token operator\">:</span> error<span class=\"token punctuation\">)</span> <span class=\"token operator\">:</span> mutation<span class=\"token punctuation\">.</span>error<span class=\"token punctuation\">.</span>message<span class=\"token punctuation\">}</span><span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>span<span class=\"token operator\">></span><span class=\"token punctuation\">}</span></code></pre></div><p>This shows the loading icon or the error message for both the query that fetches the notes and the mutation that handles deleting a note.</p><p>Finally, find the delete button of a note and add an <code class=\"language-text\">onClick</code> handler:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token operator\">&#x3C;</span>button className<span class=\"token operator\">=</span><span class=\"token string\">'link text-gray-400'</span> onClick<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> mutation<span class=\"token punctuation\">.</span><span class=\"token function\">mutate</span><span class=\"token punctuation\">(</span>note<span class=\"token punctuation\">)</span><span class=\"token punctuation\">}</span><span class=\"token operator\">></span>Delete<span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>button<span class=\"token operator\">></span></code></pre></div><p>On click, the mutation responsible for deleting the note is triggered using <code class=\"language-text\">mutation.mutate</code>. You pass it the note to delete which is the current note in a <code class=\"language-text\">map</code> loop.</p><h3 id=\"test-deleting-a-note\">Test Deleting a Note</h3><p>Rerun your server and React app if they're not running. Then, open the website again at <code class=\"language-text\">localhost:3000</code>. Click the Delete link for any of your notes. If the note is deleted successfully, an alert will be shown.</p><figure class=\"kg-card kg-image-card\"><img src=\"https://backend.shahednasser.com/content/images/2022/07/Screen-Shot-2022-07-01-at-2.48.53-PM.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"1006\" height=\"314\" srcset=\"https://backend.shahednasser.com/content/images/size/w600/2022/07/Screen-Shot-2022-07-01-at-2.48.53-PM.png 600w, https://backend.shahednasser.com/content/images/size/w1000/2022/07/Screen-Shot-2022-07-01-at-2.48.53-PM.png 1000w, https://backend.shahednasser.com/content/images/2022/07/Screen-Shot-2022-07-01-at-2.48.53-PM.png 1006w\" sizes=\"(min-width: 720px) 720px\"></figure><p>After closing the alert, the notes will be fetched again and displayed, if there are any other notes.</p><figure class=\"kg-card kg-image-card\"><img src=\"https://backend.shahednasser.com/content/images/2022/07/Screen-Shot-2022-06-28-at-9.10.04-PM-1.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"1446\" height=\"490\" srcset=\"https://backend.shahednasser.com/content/images/size/w600/2022/07/Screen-Shot-2022-06-28-at-9.10.04-PM-1.png 600w, https://backend.shahednasser.com/content/images/size/w1000/2022/07/Screen-Shot-2022-06-28-at-9.10.04-PM-1.png 1000w, https://backend.shahednasser.com/content/images/2022/07/Screen-Shot-2022-06-28-at-9.10.04-PM-1.png 1446w\" sizes=\"(min-width: 720px) 720px\"></figure><h2 id=\"conclusion\">Conclusion</h2><p>Using React (TanStack) Query, you can easily handle server data fetching and manipulation on your website with advanced features such as caching and synchronization across your React app.</p><p>Make sure to check out the <a href=\"https://tanstack.com/query/v4\">official documentation</a> to learn more about what you can do with React Query.</p>","htmlAst":{"type":"root","children":[{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"React Query (now rebranded to TanStack Query) is a React library used to make fetching and manipulating server-side data easier. Using React Query, you can implement, along with data fetching, caching, and synchronization of your data with the server."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"In this tutorial, you'll build a simple Node.js server and then learn how to interact with it on a React website using React Query."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Please note that this version uses v4 of React Query which is now named TanStack Query."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"You can find the code for this tutorial in "},{"type":"element","tagName":"a","properties":{"href":"https://github.com/shahednasser/react-query-tutorial"},"children":[{"type":"text","value":"this GitHub repository"}]},{"type":"text","value":"."}]},{"type":"element","tagName":"h2","properties":{"id":"prerequisites"},"children":[{"type":"text","value":"Prerequisites"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":" Before starting with this tutorial make sure you have "},{"type":"element","tagName":"a","properties":{"href":"https://nodejs.org/en/"},"children":[{"type":"text","value":"Node.js installed"}]},{"type":"text","value":". You need at least version 14."}]},{"type":"element","tagName":"h2","properties":{"id":"server-setup"},"children":[{"type":"text","value":"Server Setup"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"In this section, you'll set up a simple Node.js server with an SQLite database. The server has 3 endpoints to fetch, add, and delete notes."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"If you already have a server you can skip this section and go to the Website Setup section."}]},{"type":"element","tagName":"h3","properties":{"id":"create-server-project"},"children":[{"type":"text","value":"Create Server Project"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Create a new directory called "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"server"}]},{"type":"text","value":" then initialize a new project using NPM:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"bash"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-bash"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-bash"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"mkdir"}]},{"type":"text","value":" server\n"},{"type":"element","tagName":"span","properties":{"className":["token","builtin","class-name"]},"children":[{"type":"text","value":"cd"}]},{"type":"text","value":" server\n"},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"npm"}]},{"type":"text","value":" init -y"}]}]}]},{"type":"element","tagName":"h3","properties":{"id":"install-dependencies"},"children":[{"type":"text","value":"Install Dependencies"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Then, install the packages you'll need for the development of the server:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"bash"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-bash"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-bash"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"npm"}]},{"type":"text","value":" i express cors body-parser sqlite3 nodemon"}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Here's what each of the packages is for:"}]},{"type":"element","tagName":"ol","properties":{},"children":[{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"express"}]},{"type":"text","value":" to create a server using "},{"type":"element","tagName":"a","properties":{"href":"https://expressjs.com/"},"children":[{"type":"text","value":"Express"}]},{"type":"text","value":"."}]},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"cors"}]},{"type":"text","value":" is an Express middleware used to handle "},{"type":"element","tagName":"a","properties":{"href":"https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS"},"children":[{"type":"text","value":"CORS"}]},{"type":"text","value":" on your server."}]},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"body-parser"}]},{"type":"text","value":" is an Express middleware used to parse the body of a request."}]},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"sqlite3"}]},{"type":"text","value":" is an SQLite database adapter for Node.js."}]},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"nodemon"}]},{"type":"text","value":" is a library used to restart the server whenever new changes occur to the files."}]}]},{"type":"element","tagName":"h3","properties":{"id":"create-server"},"children":[{"type":"text","value":"Create Server"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Create the file "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"index.js"}]},{"type":"text","value":" with the following content:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" express "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"require"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'express'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" app "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"express"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" port "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"3001"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" cors "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"require"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'cors'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" sqlite3 "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"require"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'sqlite3'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"verbose"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" bodyParser "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"require"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'body-parser'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n\napp"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"use"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"bodyParser"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"json"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\napp"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"use"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"cors"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n\napp"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"listen"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"port"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n  console"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"log"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","template-string"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","template-punctuation","string"]},"children":[{"type":"text","value":"`"}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"Notes app listening on port "}]},{"type":"element","tagName":"span","properties":{"className":["token","interpolation"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","interpolation-punctuation","punctuation"]},"children":[{"type":"text","value":"${"}]},{"type":"text","value":"port"},{"type":"element","tagName":"span","properties":{"className":["token","interpolation-punctuation","punctuation"]},"children":[{"type":"text","value":"}"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","template-punctuation","string"]},"children":[{"type":"text","value":"`"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"This initializes the server using Express on port "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"3001"}]},{"type":"text","value":". It also uses the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"cors"}]},{"type":"text","value":" and "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"body-parser"}]},{"type":"text","value":" middleware."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Then, in "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"package.json"}]},{"type":"text","value":" add a new script "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"start"}]},{"type":"text","value":" to run the server:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"json"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-json"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-json"]},"children":[{"type":"text","value":"  "},{"type":"element","tagName":"span","properties":{"className":["token","property"]},"children":[{"type":"text","value":"\"scripts\""}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","property"]},"children":[{"type":"text","value":"\"start\""}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"nodemon index.js\""}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]}]}]}]},{"type":"element","tagName":"h3","properties":{"id":"initialize-the-database"},"children":[{"type":"text","value":"Initialize the Database"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"In "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"index.js"}]},{"type":"text","value":" before "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"app.listen"}]},{"type":"text","value":" add the following code:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" db "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"new"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","class-name"]},"children":[{"type":"text","value":"sqlite3"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"Database"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'data.db'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"err"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"if"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"err"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"throw"}]},{"type":"text","value":" err"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n\n  "},{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"// create tables if they don't exist"}]},{"type":"text","value":"\n  db"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"serialize"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n    db"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"run"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","template-string"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","template-punctuation","string"]},"children":[{"type":"text","value":"`"}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"CREATE TABLE IF NOT EXISTS notes (id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT, content TEXT, \n      created_at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP)"}]},{"type":"element","tagName":"span","properties":{"className":["token","template-punctuation","string"]},"children":[{"type":"text","value":"`"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"This creates a new database if it doesn't exist in the file "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"data.db"}]},{"type":"text","value":". Then, if the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"notes"}]},{"type":"text","value":" table doesn't exist on the database it creates it as well."}]},{"type":"element","tagName":"h3","properties":{"id":"add-endpoints"},"children":[{"type":"text","value":"Add Endpoints"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Following the database code, add the following code to add the endpoints:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"text","value":"app"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"get"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'/notes'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"req"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" res"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n  db"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"all"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'SELECT * FROM notes'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"err"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" rows"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"if"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"err"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n      console"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"error"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"err"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" res"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"status"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"500"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"json"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"success"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","boolean"]},"children":[{"type":"text","value":"false"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"message"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'An error occurred, please try again later'"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n\n    "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" res"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"json"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"success"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","boolean"]},"children":[{"type":"text","value":"true"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"data"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" rows "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n\napp"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"get"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'/notes/:id'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"req"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" res"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n  db"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"get"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'SELECT * FROM notes WHERE id = ?'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" req"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"params"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"id"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"err"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" row"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"if"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"err"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n      console"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"error"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"err"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" res"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"status"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"500"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"json"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"success"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","boolean"]},"children":[{"type":"text","value":"false"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"message"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'An error occurred, please try again later'"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n\n    "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"if"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"!"}]},{"type":"text","value":"row"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" res"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"status"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"404"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"json"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"success"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","boolean"]},"children":[{"type":"text","value":"false"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"message"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'Note does not exist'"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n\n    "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" res"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"json"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"success"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","boolean"]},"children":[{"type":"text","value":"true"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"data"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" row "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n\napp"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"post"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'/notes'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"req"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" res"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" title"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" content "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" req"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"body"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n\n  "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"if"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"!"}]},{"type":"text","value":"title "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"||"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"!"}]},{"type":"text","value":"content"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" res"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"status"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"400"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"json"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"success"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","boolean"]},"children":[{"type":"text","value":"false"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"message"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'title and content are required'"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n\n  db"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"run"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'INSERT INTO notes (title, content) VALUES (?, ?)'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"["}]},{"type":"text","value":"title"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" content"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"]"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"function"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"err"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"if"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"err"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n      console"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"error"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"err"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" res"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"status"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"500"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"json"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"success"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","boolean"]},"children":[{"type":"text","value":"false"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"message"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'An error occurred, please try again later'"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n\n    "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" res"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"json"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"success"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","boolean"]},"children":[{"type":"text","value":"true"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"data"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"id"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"this"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"lastID"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n        title"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n        content"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n\napp"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"delete"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'/notes/:id'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"req"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" res"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" id "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" req"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"params"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n\n  db"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"get"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'SELECT * FROM notes WHERE id = ?'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"["}]},{"type":"text","value":"id"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"]"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"err"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" row"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"if"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"err"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n      console"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"error"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"err"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" res"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"status"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"500"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"json"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"success"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","boolean"]},"children":[{"type":"text","value":"false"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"message"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'An error occurred, please try again later'"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n\n    "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"if"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"!"}]},{"type":"text","value":"row"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" res"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"status"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"404"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"json"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"success"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","boolean"]},"children":[{"type":"text","value":"false"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"message"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'Note does not exist'"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n\n    db"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"run"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'DELETE FROM notes WHERE id = ?'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"["}]},{"type":"text","value":"id"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"]"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"error"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"if"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"error"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n        console"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"error"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"error"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" res"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"status"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"500"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"json"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"success"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","boolean"]},"children":[{"type":"text","value":"false"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"message"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'An error occurred, please try again later'"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n\n      "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" res"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"json"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"success"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","boolean"]},"children":[{"type":"text","value":"true"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"message"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'Note deleted successfully'"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Briefly, this creates 4 endpoints:"}]},{"type":"element","tagName":"ol","properties":{},"children":[{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"/notes"}]},{"type":"text","value":" endpoint of the method "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"GET"}]},{"type":"text","value":" to fetch all notes."}]},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"/notes/:id"}]},{"type":"text","value":" endpoint of the method "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"GET"}]},{"type":"text","value":" to fetch a note by an ID."}]},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"/notes"}]},{"type":"text","value":" endpoint of the method "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"POST"}]},{"type":"text","value":" to add a note."}]},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"/notes/:id"}]},{"type":"text","value":" endpoint of the method "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"DELETE"}]},{"type":"text","value":" to delete a note."}]}]},{"type":"element","tagName":"h3","properties":{"id":"test-server"},"children":[{"type":"text","value":"Test Server"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Run the following command to start the server:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"bash"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-bash"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-bash"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"npm"}]},{"type":"text","value":" start"}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"This starts the server on port "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"3001"}]},{"type":"text","value":". You can test it out by sending a request to "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"localhost:3001/notes"}]},{"type":"text","value":"."}]},{"type":"element","tagName":"h2","properties":{"id":"website-setup"},"children":[{"type":"text","value":"Website Setup"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"In this section, you'll create the website with Create React App (CRA). This is where you'll make use of React Query."}]},{"type":"element","tagName":"h3","properties":{"id":"create-website-project"},"children":[{"type":"text","value":"Create Website Project"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"To create a new React app, run the following command in a different directory:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"bash"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-bash"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-bash"]},"children":[{"type":"text","value":"npx create-react-app website"}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"This creates a new React app in the directory "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"website"}]},{"type":"text","value":"."}]},{"type":"element","tagName":"h3","properties":{"id":"install-dependencies-1"},"children":[{"type":"text","value":"Install Dependencies"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Run the following command to change to the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"website"}]},{"type":"text","value":" directory and install the necessary dependencies for the website:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"bash"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-bash"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-bash"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","builtin","class-name"]},"children":[{"type":"text","value":"cd"}]},{"type":"text","value":" website\n"},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"npm"}]},{"type":"text","value":" i @tanstack/react-query tailwindcss postcss autoprefixer @tailwindcss/typography @heroicons/react @windmill/react-ui"}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"The "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"@tanstack/react-query"}]},{"type":"text","value":" library is the React Query library which is now named TanStack Query. The other libraries are "},{"type":"element","tagName":"a","properties":{"href":"https://tailwindcss.com/"},"children":[{"type":"text","value":"Tailwind CSS"}]},{"type":"text","value":" related libraries to add styling to the website."}]},{"type":"element","tagName":"h3","properties":{"id":"tailwind-css-setup"},"children":[{"type":"text","value":"Tailwind CSS Setup"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"This section is optional and is only used to set up Tailwind CSS."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Create the file "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"postcss.config.js"}]},{"type":"text","value":" with the following content:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"text","value":"module"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"exports "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"plugins"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"tailwindcss"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"autoprefixer"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n"}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Also, create the file "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"tailwind.config.js"}]},{"type":"text","value":" with the following content:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"/** @type {import('tailwindcss').Config} */"}]},{"type":"text","value":"\nmodule"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"exports "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"content"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"["}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"./src/**/*.{js,jsx,ts,tsx}\""}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"]"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"theme"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"extend"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"plugins"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"["}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"require"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'@tailwindcss/typography'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"]"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n"}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Then, create the file "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"src/index.css"}]},{"type":"text","value":" with the following content:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"css"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-css"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-css"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","atrule"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","rule"]},"children":[{"type":"text","value":"@tailwind"}]},{"type":"text","value":" base"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","atrule"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","rule"]},"children":[{"type":"text","value":"@tailwind"}]},{"type":"text","value":" components"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","atrule"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","rule"]},"children":[{"type":"text","value":"@tailwind"}]},{"type":"text","value":" utilities"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]}]}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Finally, in "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"index.js"}]},{"type":"text","value":" import "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"src/index.css"}]},{"type":"text","value":" at the beginning of the file:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"import"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'./index.css'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]}]}]}]},{"type":"element","tagName":"h3","properties":{"id":"use-queryclientprovider"},"children":[{"type":"text","value":"Use QueryClientProvider"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"To use the React Query client in all of your components, you must use it at a high level in your website's components hierarchy. The best place to put it is in "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"src/index.js"}]},{"type":"text","value":" which wraps up your entire website's components."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"In "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"src/index.js"}]},{"type":"text","value":" add the following imports at the beginning of the file:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"import"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n  QueryClient"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n  QueryClientProvider"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"from"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'@tanstack/react-query'"}]}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Then, initialize a new Query client:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" queryClient "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"new"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","class-name"]},"children":[{"type":"text","value":"QueryClient"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Finally, change the parameter passed to "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"root.render"}]},{"type":"text","value":":"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"text","value":"root"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"render"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"QueryClientProvider client"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"queryClient"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"App "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"QueryClientProvider"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"This wraps the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"App"}]},{"type":"text","value":" component which holds the rest of the website's components with "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"QueryClientProvider"}]},{"type":"text","value":". This provider accepts the prop "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"client"}]},{"type":"text","value":" which is an instance of "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"QueryClient"}]},{"type":"text","value":"."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Now, all components within the website will have access to the Query Client which is used to fetch, cache, and manipulate the server data."}]},{"type":"element","tagName":"h3","properties":{"id":"implement-display-notes"},"children":[{"type":"text","value":"Implement Display Notes"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Fetching data from the server is an act of performing a query. Therefore, you'll use "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"useQuery"}]},{"type":"text","value":" in this section."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"You'll display notes in the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"App"}]},{"type":"text","value":" component. These notes are fetched from the server using the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"/notes"}]},{"type":"text","value":" endpoint."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Replace the content of "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"app.js"}]},{"type":"text","value":" with the following content:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"import"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" PlusIcon"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" RefreshIcon "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"from"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'@heroicons/react/solid'"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"import"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" useMutation"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" useQuery"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" useQueryClient "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"from"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'@tanstack/react-query'"}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"function"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"App"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" isLoading"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" isError"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" data"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" error "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"useQuery"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"["}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'notes'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"]"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" fetchNotes"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n\n  "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"function"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"fetchNotes"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"fetch"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'http://localhost:3001/notes'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"then"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"response"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" response"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"json"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"then"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" success"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" data "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"if"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"!"}]},{"type":"text","value":"success"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"throw"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"new"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","class-name"]},"children":[{"type":"text","value":"Error"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'An error occurred while fetching notes'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" data"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n\n  "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"div className"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"w-screen h-screen overflow-x-hidden bg-red-400 flex flex-col justify-center items-center\""}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"div className"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'bg-white w-full md:w-1/2 p-5 text-center rounded shadow-md text-gray-800 prose'"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"h1"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"Notes"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"h1"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"isLoading "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"&&"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"RefreshIcon className"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"w-10 h-10 animate-spin mx-auto\""}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"RefreshIcon"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"isError "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"&&"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"span className"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'text-red'"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"error"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"message "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"?"}]},{"type":"text","value":" error"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"message "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" error"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"span"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"!"}]},{"type":"text","value":"isLoading "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"&&"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"!"}]},{"type":"text","value":"isError "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"&&"}]},{"type":"text","value":" data "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"&&"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"!"}]},{"type":"text","value":"data"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"length "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"&&"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"span className"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'text-red-400'"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"You have no notes"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"span"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"data "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"&&"}]},{"type":"text","value":" data"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"length "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"0"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"&&"}]},{"type":"text","value":" data"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"map"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"note"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" index"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"\n          "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"div key"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"note"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"id"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" className"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"element","tagName":"span","properties":{"className":["token","template-string"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","template-punctuation","string"]},"children":[{"type":"text","value":"`"}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"text-left "}]},{"type":"element","tagName":"span","properties":{"className":["token","interpolation"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","interpolation-punctuation","punctuation"]},"children":[{"type":"text","value":"${"}]},{"type":"text","value":"index "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"!=="}]},{"type":"text","value":" data"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"length "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"-"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"1"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"?"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'border-b pb-2'"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"''"}]},{"type":"element","tagName":"span","properties":{"className":["token","interpolation-punctuation","punctuation"]},"children":[{"type":"text","value":"}"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","template-punctuation","string"]},"children":[{"type":"text","value":"`"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n            "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"h2"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"note"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"title"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"h2"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n            "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"p"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"note"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"content"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"p"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n            "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"span"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n              "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"button className"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'link text-gray-400'"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"Delete"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"button"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n            "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"span"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n          "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"div"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"div"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"button className"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"mt-2 bg-gray-700 hover:bg-gray-600 rounded-full text-white p-3\""}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"PlusIcon className"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'w-5 h-5'"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"PlusIcon"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"button"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"div"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"export"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"default"}]},{"type":"text","value":" App"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Here's briefly what's going on in this code snippet:"}]},{"type":"element","tagName":"ol","properties":{},"children":[{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"You use "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"useQuery"}]},{"type":"text","value":" to fetch the notes. The first parameter it accepts is a unique key used for caching. The second parameter is the function used to fetch the data. You pass it the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"fetchNotes"}]},{"type":"text","value":" function."}]},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"useQuery"}]},{"type":"text","value":" returns an object that holds "},{"type":"element","tagName":"a","properties":{"href":"https://tanstack.com/query/v4/docs/reference/useQuery"},"children":[{"type":"text","value":"many variables"}]},{"type":"text","value":". Here, you use 4 of them: "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"isLoading"}]},{"type":"text","value":" is a boolean value that determines whether the data is currently being fetched; "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"isError"}]},{"type":"text","value":" is a boolean value that determines if an error occurred. "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"data"}]},{"type":"text","value":" is the data that is fetched from the server; and "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"error"}]},{"type":"text","value":" is the error message if "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"isError"}]},{"type":"text","value":" is true."}]},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"The "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"fetchNotes"}]},{"type":"text","value":" function must return a promise that either resolves data or throws an error. In the function, you send a "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"GET"}]},{"type":"text","value":" request to "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"localhost:3001/notes"}]},{"type":"text","value":" to fetch the notes. If the data is fetched successfully it is returned in the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"then"}]},{"type":"text","value":" fulfillment function. "}]},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"In the returned JSX, if "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"isLoading"}]},{"type":"text","value":" is true, a loading icon is shown. If "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"isError"}]},{"type":"text","value":" is true, an error message is shown. If "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"data"}]},{"type":"text","value":" is fetched successfully and has any data in it, the notes are rendered."}]},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"You also show a button with a plus icon to add new notes. You'll implement this later."}]}]},{"type":"element","tagName":"h3","properties":{"id":"test-displaying-notes"},"children":[{"type":"text","value":"Test Displaying Notes"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"To test out what you've implemented so far, make sure your server is still running, then start your React app server with the following command:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"bash"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-bash"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-bash"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"npm"}]},{"type":"text","value":" start"}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"This runs your React app on "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"localhost:3000"}]},{"type":"text","value":" by default. If you open it in your browser, you'll see a loading icon at first then you'll see no notes as you haven't added any yet."}]},{"type":"element","tagName":"figure","properties":{"className":["kg-card","kg-image-card"]},"children":[{"type":"element","tagName":"img","properties":{"src":"https://backend.shahednasser.com/content/images/2022/07/Screen-Shot-2022-06-28-at-9.10.04-PM.png","className":["kg-image"],"alt":"","loading":"lazy","width":1446,"height":490,"srcSet":["https://backend.shahednasser.com/content/images/size/w600/2022/07/Screen-Shot-2022-06-28-at-9.10.04-PM.png 600w","https://backend.shahednasser.com/content/images/size/w1000/2022/07/Screen-Shot-2022-06-28-at-9.10.04-PM.png 1000w","https://backend.shahednasser.com/content/images/2022/07/Screen-Shot-2022-06-28-at-9.10.04-PM.png 1446w"],"sizes":"(min-width: 720px) 720px"},"children":[]}]},{"type":"element","tagName":"h3","properties":{"id":"implement-add-notes-functionality"},"children":[{"type":"text","value":"Implement Add Notes Functionality"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Adding a note is an act of mutation on the server data. Therefore, you'll be using the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"useMutation"}]},{"type":"text","value":" hook in this section."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"You'll create a separate component that shows the form used to add a note."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Create the file "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"src/form.js"}]},{"type":"text","value":" with the following content:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"import"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" useMutation"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" useQueryClient "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"from"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'@tanstack/react-query'"}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"import"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" useState "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"from"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'react'"}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"export"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"default"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"function"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"Form"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" isOpen"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" setIsOpen "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"["}]},{"type":"text","value":"title"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" setTitle"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"]"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"useState"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"\""}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"["}]},{"type":"text","value":"content"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" setContent"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"]"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"useState"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"\""}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" queryClient "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"useQueryClient"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n\n  "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" mutation "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"useMutation"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"insertNote"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","function-variable","function"]},"children":[{"type":"text","value":"onSuccess"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"setTitle"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"\""}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"setContent"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"\""}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n\n  "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"function"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"closeForm"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"e"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n    e"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"preventDefault"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"setIsOpen"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","boolean"]},"children":[{"type":"text","value":"false"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n\n  "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"function"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"insertNote"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"fetch"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","template-string"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","template-punctuation","string"]},"children":[{"type":"text","value":"`"}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"http://localhost:3001/notes"}]},{"type":"element","tagName":"span","properties":{"className":["token","template-punctuation","string"]},"children":[{"type":"text","value":"`"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"method"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'POST'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"headers"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","string-property","property"]},"children":[{"type":"text","value":"'Content-Type'"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'application/json'"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"body"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","constant"]},"children":[{"type":"text","value":"JSON"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"stringify"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n        title"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n        content\n      "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"then"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"response"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" response"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"json"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"then"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" success"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" data "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"if"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"!"}]},{"type":"text","value":"success"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"throw"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"new"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","class-name"]},"children":[{"type":"text","value":"Error"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"An error occured\""}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n      \n      "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"setIsOpen"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","boolean"]},"children":[{"type":"text","value":"false"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n      queryClient"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"setQueriesData"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'notes'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"old"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"["}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"..."}]},{"type":"text","value":"old"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" data"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"]"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n\n  "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"function"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"handleSubmit"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"e"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n    e"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"preventDefault"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n    mutation"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"mutate"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n\n  "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"div className"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"element","tagName":"span","properties":{"className":["token","template-string"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","template-punctuation","string"]},"children":[{"type":"text","value":"`"}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"absolute w-full h-full top-0 left-0 z-50 flex justify-center items-center "}]},{"type":"element","tagName":"span","properties":{"className":["token","interpolation"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","interpolation-punctuation","punctuation"]},"children":[{"type":"text","value":"${"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"!"}]},{"type":"text","value":"isOpen "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"?"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'hidden'"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"''"}]},{"type":"element","tagName":"span","properties":{"className":["token","interpolation-punctuation","punctuation"]},"children":[{"type":"text","value":"}"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","template-punctuation","string"]},"children":[{"type":"text","value":"`"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"div className"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'bg-black opacity-50 absolute w-full h-full top-0 left-0'"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"div"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"form className"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'bg-white w-full md:w-1/2 p-5 rounded shadow-md text-gray-800 prose relative'"}]},{"type":"text","value":" \n        onSubmit"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"handleSubmit"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"h2 className"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'text-center'"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"Add Note"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"h2"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"mutation"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"isError "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"&&"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"span className"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'block mb-2 text-red-400'"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"mutation"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"error"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"message "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"?"}]},{"type":"text","value":" mutation"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"error"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"message "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" mutation"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"error"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"span"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"input type"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"text\""}]},{"type":"text","value":" placeholder"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'Title'"}]},{"type":"text","value":" className"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'rounded-sm w-full border px-2'"}]},{"type":"text","value":" \n          value"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"title"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" onChange"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"e"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"setTitle"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"e"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"target"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"value"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"textarea onChange"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"e"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"setContent"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"e"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"target"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"value"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" \n          className"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"rounded-sm w-full border px-2 mt-2\""}]},{"type":"text","value":" placeholder"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'Content'"}]},{"type":"text","value":" value"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"content"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"textarea"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"div"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n          "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"button type"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"submit\""}]},{"type":"text","value":" className"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'mt-2 bg-red-400 hover:bg-red-600 text-white p-3 rounded mr-2 disabled:pointer-events-none'"}]},{"type":"text","value":" \n            disabled"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"mutation"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"isLoading"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n            Add"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"button"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n          "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"button className"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'mt-2 bg-gray-700 hover:bg-gray-600 text-white p-3 rounded'"}]},{"type":"text","value":"\n            onClick"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"closeForm"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"Cancel"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"button"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"div"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"form"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"div"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Here's a brief explanation of this form"}]},{"type":"element","tagName":"ol","properties":{},"children":[{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"This form acts as a pop-up. It accepts "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"isOpen"}]},{"type":"text","value":" and "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"setIsOpen"}]},{"type":"text","value":" props to determine when the form is opened and handle closing it."}]},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"You use "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"useQueryClient"}]},{"type":"text","value":" to get access to the Query Client. This is necessary to perform a mutation."}]},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"To handle adding a note on your server and keep all data in your query client synced, you must the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"useMutation"}]},{"type":"text","value":" hook. "}]},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"The "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"useMutation"}]},{"type":"text","value":" hook accepts 2 parameters. Thie first one is the function that will handle the mutation, which in this case is "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"insertNote"}]},{"type":"text","value":". The second parameter is an object of "},{"type":"element","tagName":"a","properties":{"href":"https://tanstack.com/query/v4/docs/reference/useMutation"},"children":[{"type":"text","value":"options"}]},{"type":"text","value":". You pass it one option "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"onSuccess"}]},{"type":"text","value":" which is a function that runs if the mutation is performed successfully. You use this to reset the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"title"}]},{"type":"text","value":" and "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"content"}]},{"type":"text","value":" fields of the form."}]},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"In "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"insertNote"}]},{"type":"text","value":", you send a "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"POST"}]},{"type":"text","value":" request to "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"localhost:3001/notes"}]},{"type":"text","value":" and pass in the body the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"title"}]},{"type":"text","value":" and "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"content"}]},{"type":"text","value":" of the note to be created. If the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"success"}]},{"type":"text","value":" body parameter returned from the server is "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"false"}]},{"type":"text","value":", an error is thrown to signal that the mutation failed. "}]},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"If the note is added successfully, you change the cached value of the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"notes"}]},{"type":"text","value":" key using the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"queryClient.setQueriesData"}]},{"type":"text","value":" method. This method accepts the key as a first parameter and the new data associated with that key as a second parameter. This updates the data everywhere it's used on your website."}]},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"In this component you display a form with 2 fields: "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"title"}]},{"type":"text","value":" and "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"content"}]},{"type":"text","value":". In the form, you check if an error occurs using "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"mutation.isError"}]},{"type":"text","value":" and get access to the error using "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"mutation.error"}]},{"type":"text","value":"."}]},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"You handle form submission in the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"handleSubmit"}]},{"type":"text","value":" function. Here, you trigger the mutation using "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"mutation.mutate"}]},{"type":"text","value":". This is where the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"insertNote"}]},{"type":"text","value":" function is triggered to add a new note."}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Then, in "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"src/app.js"}]},{"type":"text","value":" add the following imports at the beginning of the file:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"import"}]},{"type":"text","value":" Form "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"from"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'./form'"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"import"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" useState "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"from"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'react'"}]}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Then, at the beginning of the component add a new state variable to manage wheter the form is opened or not:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"["}]},{"type":"text","value":"isOpen"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" setIsOpen"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"]"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"useState"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","boolean"]},"children":[{"type":"text","value":"false"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Next, add a new function "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"addNote"}]},{"type":"text","value":" that just uses "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"setIsOpen"}]},{"type":"text","value":" to open the form:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"function"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"addNote"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"setIsOpen"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","boolean"]},"children":[{"type":"text","value":"true"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Finally, in the returned JSX, replace the button with the plus icon with the following:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"button className"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"mt-2 bg-gray-700 hover:bg-gray-600 rounded-full text-white p-3\""}]},{"type":"text","value":" onClick"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"addNote"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"PlusIcon className"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'w-5 h-5'"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"PlusIcon"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"button"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"Form isOpen"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"isOpen"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" setIsOpen"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"setIsOpen"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"This sets the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"onClick"}]},{"type":"text","value":" handler of the button to "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"addNote"}]},{"type":"text","value":". It also adds the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"Form"}]},{"type":"text","value":" component you created earlier as a child component of "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"App"}]},{"type":"text","value":". "}]},{"type":"element","tagName":"h3","properties":{"id":"test-adding-a-note"},"children":[{"type":"text","value":"Test Adding a Note"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Rerun your server and React app if they're not running. Then, open the website again at "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"localhost:3000"}]},{"type":"text","value":". Click on the plus button and a pop up will open with the form to add a new note."}]},{"type":"element","tagName":"figure","properties":{"className":["kg-card","kg-image-card"]},"children":[{"type":"element","tagName":"img","properties":{"src":"https://backend.shahednasser.com/content/images/2022/07/Screen-Shot-2022-07-24-at-6.31.41-PM.png","className":["kg-image"],"alt":"","loading":"lazy","width":1494,"height":792,"srcSet":["https://backend.shahednasser.com/content/images/size/w600/2022/07/Screen-Shot-2022-07-24-at-6.31.41-PM.png 600w","https://backend.shahednasser.com/content/images/size/w1000/2022/07/Screen-Shot-2022-07-24-at-6.31.41-PM.png 1000w","https://backend.shahednasser.com/content/images/2022/07/Screen-Shot-2022-07-24-at-6.31.41-PM.png 1494w"],"sizes":"(min-width: 720px) 720px"},"children":[]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Enter a random title and content then click Add. The pop up form will then close and you can see the new note added."}]},{"type":"element","tagName":"figure","properties":{"className":["kg-card","kg-image-card"]},"children":[{"type":"element","tagName":"img","properties":{"src":"https://backend.shahednasser.com/content/images/2022/07/Screen-Shot-2022-07-24-at-6.32.53-PM.png","className":["kg-image"],"alt":"","loading":"lazy","width":1418,"height":720,"srcSet":["https://backend.shahednasser.com/content/images/size/w600/2022/07/Screen-Shot-2022-07-24-at-6.32.53-PM.png 600w","https://backend.shahednasser.com/content/images/size/w1000/2022/07/Screen-Shot-2022-07-24-at-6.32.53-PM.png 1000w","https://backend.shahednasser.com/content/images/2022/07/Screen-Shot-2022-07-24-at-6.32.53-PM.png 1418w"],"sizes":"(min-width: 720px) 720px"},"children":[]}]},{"type":"element","tagName":"h3","properties":{"id":"implement-delete-note-functionality"},"children":[{"type":"text","value":"Implement Delete Note Functionality"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"The last functionality you'll add is deleting notes. Deleting a note is another act of mutation as it manipulates the server's data."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"At the beginning of the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"App"}]},{"type":"text","value":" component in "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"src/app.js"}]},{"type":"text","value":" add the following code:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" queryClient "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"useQueryClient"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" mutation "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"useMutation"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"deleteNote"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","function-variable","function"]},"children":[{"type":"text","value":"onSuccess"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" queryClient"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"invalidateQueries"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'notes'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Here, you get access to the query client using "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"useQueryClient"}]},{"type":"text","value":". Then, you create a new mutation using "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"useMutation"}]},{"type":"text","value":". You pass it the function "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"deleteNote"}]},{"type":"text","value":" (which you'll create next) as a first parameter and an object of options. "}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"To the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"onSuccess"}]},{"type":"text","value":" option you pass a function that does one thing. It executes the method "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"queryClient.invalidateQueries"}]},{"type":"text","value":". This method marks the cached data for a specific key as outdated, which triggers retrieving the data again. "}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"So, once a note is deleted, the query you created earlier that executes the function "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"fetchNotes"}]},{"type":"text","value":" will be triggered and the notes will be fetched again. If you had created other queries on your website that use the same key "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"notes"}]},{"type":"text","value":", they'll also be triggered to update their data. "}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Next, add the function "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"deleteNote"}]},{"type":"text","value":" in the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"App"}]},{"type":"text","value":" component in the same file:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"function"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"deleteNote"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"note"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"fetch"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","template-string"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","template-punctuation","string"]},"children":[{"type":"text","value":"`"}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"http://localhost:3001/notes/"}]},{"type":"element","tagName":"span","properties":{"className":["token","interpolation"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","interpolation-punctuation","punctuation"]},"children":[{"type":"text","value":"${"}]},{"type":"text","value":"note"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"id"},{"type":"element","tagName":"span","properties":{"className":["token","interpolation-punctuation","punctuation"]},"children":[{"type":"text","value":"}"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","template-punctuation","string"]},"children":[{"type":"text","value":"`"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"method"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'DELETE'"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"then"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"response"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" response"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"json"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"then"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" success"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" message "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"if"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"!"}]},{"type":"text","value":"success"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"throw"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"new"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","class-name"]},"children":[{"type":"text","value":"Error"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"message"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n\n      "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"alert"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"message"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"This function receives the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"note"}]},{"type":"text","value":" to be deleted as a parameter. It sends a "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"DELETE"}]},{"type":"text","value":" request to "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"localhost:3001/notes/:id"}]},{"type":"text","value":". If the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"success"}]},{"type":"text","value":" body parameter of the response is "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"false"}]},{"type":"text","value":", an error is thrown. Otherwise, only an alert is shown."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Then, in the returned JSX of the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"App"}]},{"type":"text","value":" component, change how the loading icon and error where shown previously to the following:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"isLoading "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"||"}]},{"type":"text","value":" mutation"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"isLoading"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"&&"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"RefreshIcon className"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"w-10 h-10 animate-spin mx-auto\""}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"RefreshIcon"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"isError "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"||"}]},{"type":"text","value":" mutation"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"isError"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"&&"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"span className"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'text-red'"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"error "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"?"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"error"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"message "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"?"}]},{"type":"text","value":" error"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"message "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" error"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" mutation"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"error"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"message"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"span"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"This shows the loading icon or the error message for both the query that fetches the notes and the mutation that handles deleting a note."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Finally, find the delete button of a note and add an "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"onClick"}]},{"type":"text","value":" handler:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"button className"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'link text-gray-400'"}]},{"type":"text","value":" onClick"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" mutation"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"mutate"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"note"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"Delete"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"button"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"On click, the mutation responsible for deleting the note is triggered using "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"mutation.mutate"}]},{"type":"text","value":". You pass it the note to delete which is the current note in a "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"map"}]},{"type":"text","value":" loop."}]},{"type":"element","tagName":"h3","properties":{"id":"test-deleting-a-note"},"children":[{"type":"text","value":"Test Deleting a Note"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Rerun your server and React app if they're not running. Then, open the website again at "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"localhost:3000"}]},{"type":"text","value":". Click the Delete link for any of your notes. If the note is deleted successfully, an alert will be shown."}]},{"type":"element","tagName":"figure","properties":{"className":["kg-card","kg-image-card"]},"children":[{"type":"element","tagName":"img","properties":{"src":"https://backend.shahednasser.com/content/images/2022/07/Screen-Shot-2022-07-01-at-2.48.53-PM.png","className":["kg-image"],"alt":"","loading":"lazy","width":1006,"height":314,"srcSet":["https://backend.shahednasser.com/content/images/size/w600/2022/07/Screen-Shot-2022-07-01-at-2.48.53-PM.png 600w","https://backend.shahednasser.com/content/images/size/w1000/2022/07/Screen-Shot-2022-07-01-at-2.48.53-PM.png 1000w","https://backend.shahednasser.com/content/images/2022/07/Screen-Shot-2022-07-01-at-2.48.53-PM.png 1006w"],"sizes":"(min-width: 720px) 720px"},"children":[]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"After closing the alert, the notes will be fetched again and displayed, if there are any other notes."}]},{"type":"element","tagName":"figure","properties":{"className":["kg-card","kg-image-card"]},"children":[{"type":"element","tagName":"img","properties":{"src":"https://backend.shahednasser.com/content/images/2022/07/Screen-Shot-2022-06-28-at-9.10.04-PM-1.png","className":["kg-image"],"alt":"","loading":"lazy","width":1446,"height":490,"srcSet":["https://backend.shahednasser.com/content/images/size/w600/2022/07/Screen-Shot-2022-06-28-at-9.10.04-PM-1.png 600w","https://backend.shahednasser.com/content/images/size/w1000/2022/07/Screen-Shot-2022-06-28-at-9.10.04-PM-1.png 1000w","https://backend.shahednasser.com/content/images/2022/07/Screen-Shot-2022-06-28-at-9.10.04-PM-1.png 1446w"],"sizes":"(min-width: 720px) 720px"},"children":[]}]},{"type":"element","tagName":"h2","properties":{"id":"conclusion"},"children":[{"type":"text","value":"Conclusion"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Using React (TanStack) Query, you can easily handle server data fetching and manipulation on your website with advanced features such as caching and synchronization across your React app."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Make sure to check out the "},{"type":"element","tagName":"a","properties":{"href":"https://tanstack.com/query/v4"},"children":[{"type":"text","value":"official documentation"}]},{"type":"text","value":" to learn more about what you can do with React Query."}]}],"data":{"quirksMode":false}},"tableOfContents":[{"id":"prerequisites","heading":"Prerequisites"},{"id":"server-setup","heading":"Server Setup","items":[{"id":"create-server-project","heading":"Create Server Project"},{"id":"install-dependencies","heading":"Install Dependencies"},{"id":"create-server","heading":"Create Server"},{"id":"initialize-the-database","heading":"Initialize the Database"},{"id":"add-endpoints","heading":"Add Endpoints"},{"id":"test-server","heading":"Test Server"}]},{"id":"website-setup","heading":"Website Setup","items":[{"id":"create-website-project","heading":"Create Website Project"},{"id":"install-dependencies-1","heading":"Install Dependencies"},{"id":"tailwind-css-setup","heading":"Tailwind CSS Setup"},{"id":"use-queryclientprovider","heading":"Use QueryClientProvider"},{"id":"implement-display-notes","heading":"Implement Display Notes"},{"id":"test-displaying-notes","heading":"Test Displaying Notes"},{"id":"implement-add-notes-functionality","heading":"Implement Add Notes Functionality"},{"id":"test-adding-a-note","heading":"Test Adding a Note"},{"id":"implement-delete-note-functionality","heading":"Implement Delete Note Functionality"},{"id":"test-deleting-a-note","heading":"Test Deleting a Note"}]},{"id":"conclusion","heading":"Conclusion"}]},"featureImageSharp":{"base":"React--TanStack--Query-Tutorial-for-Beginners.jpg","publicURL":"/static/49810f1cc6a34556c1ce36e3061364ce/React--TanStack--Query-Tutorial-for-Beginners.jpg","imageMeta":{"width":1560,"height":876},"childImageSharp":{"fluid":{"base64":"data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAALABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAECBf/EABQBAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhADEAAAAduqBDD/xAAYEAACAwAAAAAAAAAAAAAAAAAAARESIP/aAAgBAQABBQKxLz//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/AT//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/AT//xAAXEAADAQAAAAAAAAAAAAAAAAAAATEg/9oACAEBAAY/AoyZ/8QAGhABAAIDAQAAAAAAAAAAAAAAAQARIDFhkf/aAAgBAQABPyFQ1Lp9hbsrD//aAAwDAQACAAMAAAAQow//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/ED//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/ED//xAAcEAEAAgEFAAAAAAAAAAAAAAABABEhIDFBUWH/2gAIAQEAAT8QUh65DDBDYx0jC08Lej//2Q==","aspectRatio":1.7808219178082192,"src":"/static/49810f1cc6a34556c1ce36e3061364ce/d5c54/React--TanStack--Query-Tutorial-for-Beginners.jpg","srcSet":"/static/49810f1cc6a34556c1ce36e3061364ce/65d8c/React--TanStack--Query-Tutorial-for-Beginners.jpg 260w,\n/static/49810f1cc6a34556c1ce36e3061364ce/c5f21/React--TanStack--Query-Tutorial-for-Beginners.jpg 520w,\n/static/49810f1cc6a34556c1ce36e3061364ce/d5c54/React--TanStack--Query-Tutorial-for-Beginners.jpg 1040w,\n/static/49810f1cc6a34556c1ce36e3061364ce/81a53/React--TanStack--Query-Tutorial-for-Beginners.jpg 1560w","srcWebp":"/static/49810f1cc6a34556c1ce36e3061364ce/e4875/React--TanStack--Query-Tutorial-for-Beginners.webp","srcSetWebp":"/static/49810f1cc6a34556c1ce36e3061364ce/dc8f3/React--TanStack--Query-Tutorial-for-Beginners.webp 260w,\n/static/49810f1cc6a34556c1ce36e3061364ce/2db4b/React--TanStack--Query-Tutorial-for-Beginners.webp 520w,\n/static/49810f1cc6a34556c1ce36e3061364ce/e4875/React--TanStack--Query-Tutorial-for-Beginners.webp 1040w,\n/static/49810f1cc6a34556c1ce36e3061364ce/f5845/React--TanStack--Query-Tutorial-for-Beginners.webp 1560w","sizes":"(max-width: 1040px) 100vw, 1040px"}}}},"prev":{"id":"Ghost__Post__62f3f8304e918d05f3537963","title":"What are Events in JavaScript and How to Handle Them?","slug":"what-are-events-in-javascript-and-how-to-handle-them","featured":true,"feature_image":"https://backend.shahednasser.com/content/images/2022/08/Events-in-JavaScript-3.jpg","excerpt":"This article helps beginners understand what Events are in JavaScript and how to handle them.","custom_excerpt":"This article helps beginners understand what Events are in JavaScript and how to handle them.","visibility":"public","created_at_pretty":"10 Aug 2022","published_at_pretty":"10 Aug 2022","updated_at_pretty":"10 Aug 2022","created_at":"2022-08-10T18:25:52.000+00:00","published_at":"2022-08-10T19:49:03.000+00:00","updated_at":"2022-08-10T19:49:03.000+00:00","meta_title":null,"meta_description":null,"og_description":null,"og_image":null,"og_title":null,"twitter_description":null,"twitter_image":null,"twitter_title":null,"authors":[{"slug":"shahed","url":"https://backend.shahednasser.com/author/shahed/","name":"Shahed Nasser","bio":null,"cover_image":null,"profile_image":"https://backend.shahednasser.com/content/images/2022/03/IMG_0591.jpg","location":null,"website":null,"twitter":null,"facebook":null,"meta_title":null,"meta_description":null,"coverImageSharp":null,"profileImageSharp":null}],"primary_author":{"slug":"shahed","url":"https://backend.shahednasser.com/author/shahed/","name":"Shahed Nasser","bio":null,"cover_image":null,"profile_image":"https://backend.shahednasser.com/content/images/2022/03/IMG_0591.jpg","location":null,"website":null,"twitter":null,"facebook":null,"meta_title":null,"meta_description":null,"coverImageSharp":null,"profileImageSharp":{"base":"IMG_0591.jpg","publicURL":"/static/ceb49c3c631485453e71e00d7f84b069/IMG_0591.jpg","imageMeta":{"width":1182,"height":1179},"childImageSharp":{"fluid":{"base64":"data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAUABQDASIAAhEBAxEB/8QAGAABAQEBAQAAAAAAAAAAAAAAAAMEAQL/xAAWAQEBAQAAAAAAAAAAAAAAAAADBAL/2gAMAwEAAhADEAAAAdXiFM6i0CohUWXoKn//xAAcEAACAgIDAAAAAAAAAAAAAAACAwESBBEhM0H/2gAIAQEAAQUCWySE3WEr7SzbXjAj4iKty+sOQ//EABYRAQEBAAAAAAAAAAAAAAAAAAERIP/aAAgBAwEBPwEhj//EABQRAQAAAAAAAAAAAAAAAAAAACD/2gAIAQIBAT8BH//EAB4QAAIBBAMBAAAAAAAAAAAAAAABIRESMUECECJx/9oACAEBAAY/ApVGWvOjzgtUwLlTZA0sdL4f/8QAHBAAAwACAwEAAAAAAAAAAAAAAAERITFBkbHB/9oACAEBAAE/IahkCy+N2GwZpjQiJHJCspUFY0QrSi+HqiW2rgf/2gAMAwEAAgADAAAAEPw3/wD/xAAYEQEBAAMAAAAAAAAAAAAAAAAAARExQf/aAAgBAwEBPxCtjDqP/8QAFxEBAQEBAAAAAAAAAAAAAAAAAQAxEf/aAAgBAgEBPxBFus6Tt//EAB8QAQEAAgIBBQAAAAAAAAAAAAERACExQWFRcYGR0f/aAAgBAQABPxAuaBPPzkO1wyX7F4wkwXanfZrFQgeqE9JgS14vVOvrERIJomVBKwt2jebAeP0yVa8h1n//2Q==","aspectRatio":1,"src":"/static/ceb49c3c631485453e71e00d7f84b069/31709/IMG_0591.jpg","srcSet":"/static/ceb49c3c631485453e71e00d7f84b069/f340b/IMG_0591.jpg 28w,\n/static/ceb49c3c631485453e71e00d7f84b069/22d64/IMG_0591.jpg 55w,\n/static/ceb49c3c631485453e71e00d7f84b069/31709/IMG_0591.jpg 110w,\n/static/ceb49c3c631485453e71e00d7f84b069/aa249/IMG_0591.jpg 165w,\n/static/ceb49c3c631485453e71e00d7f84b069/0dc33/IMG_0591.jpg 220w,\n/static/ceb49c3c631485453e71e00d7f84b069/d8257/IMG_0591.jpg 1182w","srcWebp":"/static/ceb49c3c631485453e71e00d7f84b069/8678c/IMG_0591.webp","srcSetWebp":"/static/ceb49c3c631485453e71e00d7f84b069/59cda/IMG_0591.webp 28w,\n/static/ceb49c3c631485453e71e00d7f84b069/7da75/IMG_0591.webp 55w,\n/static/ceb49c3c631485453e71e00d7f84b069/8678c/IMG_0591.webp 110w,\n/static/ceb49c3c631485453e71e00d7f84b069/f282e/IMG_0591.webp 165w,\n/static/ceb49c3c631485453e71e00d7f84b069/a7b21/IMG_0591.webp 220w,\n/static/ceb49c3c631485453e71e00d7f84b069/63099/IMG_0591.webp 1182w","sizes":"(max-width: 110px) 100vw, 110px"}}}},"primary_tag":{"slug":"js","url":"https://backend.shahednasser.com/tag/js/","name":"Javascript","visibility":"public","feature_image":"https://backend.shahednasser.com/content/images/2022/01/photo-1592609931095-54a2168ae893-2.jpeg","description":"Learn more about Javascript through tutorials, articles, and tips.","meta_title":null,"meta_description":"Learn more about Javascript through tutorials, articles and tips.","featureImageSharp":{"base":"photo-1592609931095-54a2168ae893-2.jpeg","publicURL":"/static/d0b2a96dbeaa1da6e72d54edc3ccc8e2/photo-1592609931095-54a2168ae893-2.jpeg","imageMeta":{"width":2000,"height":1333},"childImageSharp":{"fluid":{"base64":"data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAANABQDASIAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAAAwAEBf/EABUBAQEAAAAAAAAAAAAAAAAAAAAB/9oADAMBAAIQAxAAAAHh6QZDjq//xAAaEAEAAwADAAAAAAAAAAAAAAABAAIREiFB/9oACAEBAAEFApQ6eO+VXFWf/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPwE//8QAFREBAQAAAAAAAAAAAAAAAAAAEDH/2gAIAQIBAT8Bp//EABoQAAICAwAAAAAAAAAAAAAAAAABECExMkH/2gAIAQEABj8CwdNXFOP/xAAcEAADAAMAAwAAAAAAAAAAAAAAAREhQVFhcYH/2gAIAQEAAT8heHx6GaR4cOQ+jrqtTQu6lgaVs//aAAwDAQACAAMAAAAQlM//xAAWEQEBAQAAAAAAAAAAAAAAAAAAARH/2gAIAQMBAT8QrH//xAAWEQEBAQAAAAAAAAAAAAAAAAABEBH/2gAIAQIBAT8QdE//xAAcEAEAAgIDAQAAAAAAAAAAAAABABEhMUFhweH/2gAIAQEAAT8QwaQHozIjaNdvYnh0/qNZJwLU36JcXxL2lqf/2Q==","aspectRatio":1.5028901734104045,"src":"/static/d0b2a96dbeaa1da6e72d54edc3ccc8e2/d5c54/photo-1592609931095-54a2168ae893-2.jpg","srcSet":"/static/d0b2a96dbeaa1da6e72d54edc3ccc8e2/65d8c/photo-1592609931095-54a2168ae893-2.jpg 260w,\n/static/d0b2a96dbeaa1da6e72d54edc3ccc8e2/c5f21/photo-1592609931095-54a2168ae893-2.jpg 520w,\n/static/d0b2a96dbeaa1da6e72d54edc3ccc8e2/d5c54/photo-1592609931095-54a2168ae893-2.jpg 1040w,\n/static/d0b2a96dbeaa1da6e72d54edc3ccc8e2/81a53/photo-1592609931095-54a2168ae893-2.jpg 1560w,\n/static/d0b2a96dbeaa1da6e72d54edc3ccc8e2/4e5f3/photo-1592609931095-54a2168ae893-2.jpg 2000w","srcWebp":"/static/d0b2a96dbeaa1da6e72d54edc3ccc8e2/e4875/photo-1592609931095-54a2168ae893-2.webp","srcSetWebp":"/static/d0b2a96dbeaa1da6e72d54edc3ccc8e2/dc8f3/photo-1592609931095-54a2168ae893-2.webp 260w,\n/static/d0b2a96dbeaa1da6e72d54edc3ccc8e2/2db4b/photo-1592609931095-54a2168ae893-2.webp 520w,\n/static/d0b2a96dbeaa1da6e72d54edc3ccc8e2/e4875/photo-1592609931095-54a2168ae893-2.webp 1040w,\n/static/d0b2a96dbeaa1da6e72d54edc3ccc8e2/f5845/photo-1592609931095-54a2168ae893-2.webp 1560w,\n/static/d0b2a96dbeaa1da6e72d54edc3ccc8e2/49d6b/photo-1592609931095-54a2168ae893-2.webp 2000w","sizes":"(max-width: 1040px) 100vw, 1040px"}}}},"tags":[{"slug":"js","url":"https://backend.shahednasser.com/tag/js/","name":"Javascript","visibility":"public","feature_image":"https://backend.shahednasser.com/content/images/2022/01/photo-1592609931095-54a2168ae893-2.jpeg","description":"Learn more about Javascript through tutorials, articles, and tips.","meta_title":null,"meta_description":"Learn more about Javascript through tutorials, articles and tips.","featureImageSharp":null}],"plaintext":"Events in JavaScript allow developers to listen for changes in the document and handle them as necessary. For example, you can listen to when a button is clicked to open a modal. Another example is showing the \"scroll up\" button when the user scrolls halfway through the page.\n\nThis article helps beginners understand what Events are in JavaScript and how to handle them.\n\n\nWhy Use Events\n\nModern websites have evolved to be interactive and reactive. Instead of presenting information or functionalities all at once, some can be shown to the user based on a specific action performed. The example mentioned earlier in the article illustrates this.\n\nEvents are also helpful in detecting different states of your website. For example, detecting when a screen is resized can help to ensure the responsiveness of certain elements on the page.\n\nThe list of use cases where events are helpful is endless. Events are an essential part of web development with JavaScript and it's important to understand how to use them.\n\n\nAdd Event Handler\n\nTo listen to events, you can use the addEventListener method. This method is available on every Element and Node in the document.\n\naddEventListener accepts three parameters: the first parameter is the name of the event to listen to; the second parameter is the function that handles this event; and the third parameter is an optional parameter that allows you to set more options for the listener.\n\nIn most cases, you only need to use the first two parameters. Here's an example of handling the click event on a button:\n\nconst button = document.querySelector(\"button\");\nbutton.addEventListener(\"click\", function (e) {\n    alert(\"Button clicked\");\n});\n\nThis retrieves the first button on the page and, when the button is clicked, shows an alert.\n\n\nCan an Event Have More Than One Handler?\n\nThe same event can have many handlers. The handlers are triggered one by one when the event occurs.\n\n\nEvent Object\n\nAs you can see, the function passed as a second parameter to addEventListener received the argument e. This is an Event object. This object may have different properties depending on its underlying type. However, it has some common important properties.\n\nA frequently used property on the Event object is the target property. This is the element that the event was triggered on. This can be helpful when you have the same handler for more than one element.\n\nFor example:\n\ndocument.querySelector(\"input\").addEventListener(\"change\", function (e) {\n    alert(e.target.value);\n});\n\nThis code snippet adds an event handler to the first input element on the change event. The change event is triggered when you change the value of the input, then move the focus from the input (for example, click on something else on the page).\n\nWhen the change event occurs and the handler is triggered, the value of the input is retrieved using e.target.value and used in an alert.\n\n\nPrevent Default Behavior of the Event\n\nIn some cases, you want to prevent the default behavior of certain events. For example, when a link is clicked on a page, you might want to show a confirmation message before the user is actually taken to a new page.\n\nTo prevent the default behavior of an event, you can use the preventDefault() method on the Event object.\n\nFor example:\n\nconst a = document.querySelector(\"a.some-link\");\na.addEventListener(\"click\", function (e) {\n    e.preventDefault();\n    if(confirm(\"Are you sure?\")) {\n      window.location.href = e.target.href;\n    }\n});\n\nThis adds an event handler to the click events on a link that has the class some-link. In the event handler, e.preventDefault() is used to prevent the default behavior of opening the page indicated in the href attribute.\n\nIt then shows the user a confirmation window, and if the user clicks Yes on the confirmation window, it then opens the page as expected.\n\n\nPrevent Other Handlers from Handling this Event\n\nAs mentioned earlier, an event can have more than one handler. However, in some cases, you might want to cancel other events from handling this event. For example, if a request is sent to the server on form submission and you don't want other event handlers of form submission to send more requests.\n\nThere are two methods that can be used to prevent other handlers from handling the same event: stopPropagation and stopImmediatePropagation.\n\nstopPropagation is used to prevent other event handlers from handling an event during the bubbling phase.\n\nBubbling is when you have the same event on both child and parent elements. The event will be triggered first on the child element, then \"bubbled\" to the parent element.\n\nIn this case, stopPropagation prevents the event from being triggered on the parent element if called in the handler of the child element. However, it does not prevent the event from propagating to other event handlers.\n\nTo prevent the event from being handled by subsequent handlers, you can use stopImmediatePropagation.\n\nFor example:\n\nconst button = document.querySelector(\"button\");\n\nbutton.addEventListener(\"click\", function (e) {\n  e.stopImmediatePropagation();\n  alert(\"Hello!\");\n});\n\nbutton.addEventListener(\"click\", function (e) {\n  alert(\"Bye!\")\n})\n\nAlthough the button has two event handlers that listen to the click event, only the first one will run since it calls the stopImmediatePropagation function.\n\n\nDifference Between preventDefault, stopPropagation, and stopImmediatePropagation\n\npreventDefault only prevents the default behavior of the event. However, it does not prevent other handlers from handling the event.\n\nstopPropagation and stopImmediatePropagation only prevent other handlers from handling the event. However, they don't prevent the default behavior of the event.\n\nIf you want to prevent both the default behavior and other handlers from handling the event, use preventDefault with either stopPropagation or stopImmediatePropagation.\n\n\nHandle Events on Dynamic Elements\n\nConsider the following example:\n\nconst buttons = document.querySelectorAll(\".btn\");\n\nbuttons.forEach((btn) => {\n  btn.addEventListener(\"click\", function (e) {\n    alert(\"Hello!\");\n  });\n})\n\n//create new button\nconst button = document.createElement('button');\nbutton.classList.add('btn');\nbutton.textContent = \"Bye\";\ndocument.body.append(button);\n\nIn this example, you first retrieve all buttons that have the class btn. Then, you loop over these buttons and add an event listener that just shows the alert \"Hello\" when the button is clicked.\n\nThen, you dynamically create a new button, add the class btn to that button, and add it to the body of the document.\n\nIf you try clicking buttons that were added in the HTML of the document or that were added prior to adding the event listener, the alert will be shown as expected. However, if you click on the new button, no alert will be shown.\n\nThis is because the element was not part of the elements retrieved using querySelectorAll as it didn't exist at the time.\n\nAlthough this is a reasonable outcome, in larger websites, you might not be able to attach an event handler every time you create a new element, or you might want to ensure that the event handler is added to all elements, whether originally or dynamically created, similarly.\n\nIn that case, instead of adding the event handler directly to each element separately, you can add the event handler to the document's body and use e.target to check if the element triggered matches a specific condition.\n\nFor example, you can transform the previous example to the following:\n\ndocument.body.addEventListener(\"click\", function (e) {\n  if (e.target.classList.contains(\"btn\")) {\n    alert(\"Hello!\");\n  }\n})\n\n//create new button\nconst button = document.createElement('button');\nbutton.classList.add('btn');\nbutton.textContent = \"Bye\";\ndocument.body.append(button);\n\nYou add a handler to the click event on the body. In the handler, you check if e.target has the class btn and only perform the necessary action if it does.\n\nNow, when any of the elements that have the class btn, whether dynamically or initially created, are clicked, the event handler will run for them.\n\nThis approach, however, will run the event listener on every click event on the body. So, it's important to handle it based on the target carefully.\n\n\nRemove Event Handler\n\nIn some cases, you might want to remove an event handler for an element. To do that, you can use the removeEventListener method. This method is available on every Element and Node in the document.\n\nThis method receives the same parameters addEventListener receives. It's important to pass the same function that you passed to addEventListener. For that reason, people commonly define the function separately, then pass it to addEventListener and removeEventListener.\n\nFor example:\n\nconst button = document.querySelector(\"button\");\n\nfunction handleClick (e) {\n  alert(\"Hello\");\n}\n\nbutton.addEventListener(\"click\", handleClick);\n\n//some time later\nbutton.removeEventListener(\"click\", handleClick);\n\n\nConclusion\n\nThis article scratches the surface of Events and helps you understand them better. To learn more about Events in JavaScript, check out the following resources:\n\n 1. Introduction to Events\n 2. Event Reference","html":"<p>Events in JavaScript allow developers to listen for changes in the document and handle them as necessary. For example, you can listen to when a button is clicked to open a modal. Another example is showing the \"scroll up\" button when the user scrolls halfway through the page.</p><p>This article helps beginners understand what Events are in JavaScript and how to handle them.</p><h2 id=\"why-use-events\">Why Use Events</h2><p>Modern websites have evolved to be interactive and reactive. Instead of presenting information or functionalities all at once, some can be shown to the user based on a specific action performed. The example mentioned earlier in the article illustrates this.</p><p>Events are also helpful in detecting different states of your website. For example, detecting when a screen is resized can help to ensure the responsiveness of certain elements on the page.</p><p>The list of use cases where events are helpful is endless. Events are an essential part of web development with JavaScript and it's important to understand how to use them.</p><h2 id=\"add-event-handler\">Add Event Handler</h2><p>To listen to events, you can use the <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener\">addEventListener</a> method. This method is available on every Element and Node in the document.</p><p><code>addEventListener</code> accepts three parameters: the first parameter is the name of the event to listen to; the second parameter is the function that handles this event; and the third parameter is an optional parameter that allows you to set more <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#parameters\">options for the listener</a>.</p><p>In most cases, you only need to use the first two parameters. Here's an example of handling the <code>click</code> event on a button:</p><pre><code class=\"language-js\">const button = document.querySelector(\"button\");\nbutton.addEventListener(\"click\", function (e) {\n    alert(\"Button clicked\");\n});</code></pre><p>This retrieves the first button on the page and, when the button is clicked, shows an alert.</p><figure class=\"kg-card kg-image-card\"><img src=\"https://backend.shahednasser.com/content/images/2022/08/Screen-Shot-2022-08-10-at-9.39.02-PM.png\" class=\"kg-image\" alt loading=\"lazy\" width=\"880\" height=\"252\" srcset=\"https://backend.shahednasser.com/content/images/size/w600/2022/08/Screen-Shot-2022-08-10-at-9.39.02-PM.png 600w, https://backend.shahednasser.com/content/images/2022/08/Screen-Shot-2022-08-10-at-9.39.02-PM.png 880w\" sizes=\"(min-width: 720px) 720px\"></figure><h3 id=\"can-an-event-have-more-than-one-handler\">Can an Event Have More Than One Handler?</h3><p>The same event can have many handlers. The handlers are triggered one by one when the event occurs.</p><h3 id=\"event-object\">Event Object</h3><p>As you can see, the function passed as a second parameter to <code>addEventListener</code> received the argument <code>e</code>. This is an <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Event\">Event</a> object. This object may have different properties depending on its underlying type. However, it has some common important properties.</p><p>A frequently used property on the Event object is the <code>target</code> property. This is the element that the event was triggered on. This can be helpful when you have the same handler for more than one element.</p><p>For example:</p><pre><code class=\"language-js\">document.querySelector(\"input\").addEventListener(\"change\", function (e) {\n    alert(e.target.value);\n});</code></pre><p>This code snippet adds an event handler to the first <code>input</code> element on the <code>change</code> event. The <code>change</code> event is triggered when you change the value of the input, then move the focus from the input (for example, click on something else on the page).</p><p>When the <code>change</code> event occurs and the handler is triggered, the value of the input is retrieved using <code>e.target.value</code> and used in an alert.</p><h3 id=\"prevent-default-behavior-of-the-event\">Prevent Default Behavior of the Event</h3><p>In some cases, you want to prevent the default behavior of certain events. For example, when a link is clicked on a page, you might want to show a confirmation message before the user is actually taken to a new page.</p><p>To prevent the default behavior of an event, you can use the <code>preventDefault()</code> method on the Event object.</p><p>For example:</p><pre><code class=\"language-js\">const a = document.querySelector(\"a.some-link\");\na.addEventListener(\"click\", function (e) {\n    e.preventDefault();\n    if(confirm(\"Are you sure?\")) {\n      window.location.href = e.target.href;\n    }\n});</code></pre><p>This adds an event handler to the <code>click</code> events on a link that has the class <code>some-link</code>. In the event handler, <code>e.preventDefault()</code> is used to prevent the default behavior of opening the page indicated in the <code>href</code> attribute.</p><p>It then shows the user a confirmation window, and if the user clicks Yes on the confirmation window, it then opens the page as expected.</p><h3 id=\"prevent-other-handlers-from-handling-this-event\">Prevent Other Handlers from Handling this Event</h3><p>As mentioned earlier, an event can have more than one handler. However, in some cases, you might want to cancel other events from handling this event. For example, if a request is sent to the server on form submission and you don't want other event handlers of form submission to send more requests.</p><p>There are two methods that can be used to prevent other handlers from handling the same event: <code>stopPropagation</code> and <code>stopImmediatePropagation</code>.</p><p><code>stopPropagation</code> is used to prevent other event handlers from handling an event during the bubbling phase. </p><p>Bubbling is when you have the same event on both child and parent elements. The event will be triggered first on the child element, then \"bubbled\" to the parent element.</p><p>In this case, <code>stopPropagation</code> prevents the event from being triggered on the parent element if called in the handler of the child element. However, it does not prevent the event from propagating to other event handlers.</p><p>To prevent the event from being handled by subsequent handlers, you can use <code>stopImmediatePropagation</code>.</p><p>For example:</p><pre><code class=\"language-js\">const button = document.querySelector(\"button\");\n\nbutton.addEventListener(\"click\", function (e) {\n  e.stopImmediatePropagation();\n  alert(\"Hello!\");\n});\n\nbutton.addEventListener(\"click\", function (e) {\n  alert(\"Bye!\")\n})</code></pre><p>Although the button has two event handlers that listen to the <code>click</code> event, only the first one will run since it calls the <code>stopImmediatePropagation</code> function.</p><h3 id=\"difference-between-preventdefault-stoppropagation-and-stopimmediatepropagation\">Difference Between preventDefault, stopPropagation, and stopImmediatePropagation</h3><p><code>preventDefault</code> only prevents the default behavior of the event. However, it does not prevent other handlers from handling the event.</p><p><code>stopPropagation</code> and <code>stopImmediatePropagation</code> only prevent other handlers from handling the event. However, they don't prevent the default behavior of the event.</p><p>If you want to prevent both the default behavior and other handlers from handling the event, use <code>preventDefault</code> with either <code>stopPropagation</code> or <code>stopImmediatePropagation</code>.</p><h3 id=\"handle-events-on-dynamic-elements\">Handle Events on Dynamic Elements</h3><p>Consider the following example:</p><pre><code class=\"language-js\">const buttons = document.querySelectorAll(\".btn\");\n\nbuttons.forEach((btn) =&gt; {\n  btn.addEventListener(\"click\", function (e) {\n    alert(\"Hello!\");\n  });\n})\n\n//create new button\nconst button = document.createElement('button');\nbutton.classList.add('btn');\nbutton.textContent = \"Bye\";\ndocument.body.append(button);</code></pre><p>In this example, you first retrieve all buttons that have the class <code>btn</code>. Then, you loop over these buttons and add an event listener that just shows the alert \"Hello\" when the button is clicked.</p><p>Then, you dynamically create a new button, add the class <code>btn</code> to that button, and add it to the <code>body</code> of the document.</p><p>If you try clicking buttons that were added in the HTML of the document or that were added prior to adding the event listener, the alert will be shown as expected. However, if you click on the new button, no alert will be shown. </p><p>This is because the element was not part of the elements retrieved using <code>querySelectorAll</code> as it didn't exist at the time.</p><p>Although this is a reasonable outcome, in larger websites, you might not be able to attach an event handler every time you create a new element, or you might want to ensure that the event handler is added to all elements, whether originally or dynamically created, similarly.</p><p>In that case, instead of adding the event handler directly to each element separately, you can add the event handler to the document's <code>body</code> and use <code>e.target</code> to check if the element triggered matches a specific condition.</p><p>For example, you can transform the previous example to the following:</p><pre><code class=\"language-js\">document.body.addEventListener(\"click\", function (e) {\n  if (e.target.classList.contains(\"btn\")) {\n    alert(\"Hello!\");\n  }\n})\n\n//create new button\nconst button = document.createElement('button');\nbutton.classList.add('btn');\nbutton.textContent = \"Bye\";\ndocument.body.append(button);</code></pre><p>You add a handler to the <code>click</code> event on the <code>body</code>. In the handler, you check if <code>e.target</code> has the class <code>btn</code> and only perform the necessary action if it does.</p><p>Now, when any of the elements that have the class <code>btn</code>, whether dynamically or initially created, are clicked, the event handler will run for them.</p><p>This approach, however, will run the event listener on every click event on the body. So, it's important to handle it based on the target carefully.</p><h2 id=\"remove-event-handler\">Remove Event Handler</h2><p>In some cases, you might want to remove an event handler for an element. To do that, you can use the <code>removeEventListener</code> method. This method is available on every Element and Node in the document.</p><p>This method receives the same parameters <code>addEventListener</code> receives. It's important to pass the same function that you passed to <code>addEventListener</code>. For that reason, people commonly define the function separately, then pass it to <code>addEventListener</code> and <code>removeEventListener</code>.</p><p>For example:</p><pre><code class=\"language-js\">const button = document.querySelector(\"button\");\n\nfunction handleClick (e) {\n  alert(\"Hello\");\n}\n\nbutton.addEventListener(\"click\", handleClick);\n\n//some time later\nbutton.removeEventListener(\"click\", handleClick);</code></pre><h2 id=\"conclusion\">Conclusion</h2><p>This article scratches the surface of Events and helps you understand them better. To learn more about Events in JavaScript, check out the following resources:</p><ol><li><a href=\"https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Events\">Introduction to Events</a></li><li><a href=\"https://developer.mozilla.org/en-US/docs/Web/Events\">Event Reference</a></li></ol>","url":"https://backend.shahednasser.com/what-are-events-in-javascript-and-how-to-handle-them/","canonical_url":null,"uuid":"9c350779-18b0-4e42-8e71-48206198db93","codeinjection_foot":null,"codeinjection_head":null,"codeinjection_styles":null,"comment_id":"62f3f8304e918d05f3537963","reading_time":6,"send_email_when_published":null,"email_subject":null,"childHtmlRehype":{"html":"<p>Events in JavaScript allow developers to listen for changes in the document and handle them as necessary. For example, you can listen to when a button is clicked to open a modal. Another example is showing the \"scroll up\" button when the user scrolls halfway through the page.</p><p>This article helps beginners understand what Events are in JavaScript and how to handle them.</p><h2 id=\"why-use-events\">Why Use Events</h2><p>Modern websites have evolved to be interactive and reactive. Instead of presenting information or functionalities all at once, some can be shown to the user based on a specific action performed. The example mentioned earlier in the article illustrates this.</p><p>Events are also helpful in detecting different states of your website. For example, detecting when a screen is resized can help to ensure the responsiveness of certain elements on the page.</p><p>The list of use cases where events are helpful is endless. Events are an essential part of web development with JavaScript and it's important to understand how to use them.</p><h2 id=\"add-event-handler\">Add Event Handler</h2><p>To listen to events, you can use the <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener\">addEventListener</a> method. This method is available on every Element and Node in the document.</p><p><code class=\"language-text\">addEventListener</code> accepts three parameters: the first parameter is the name of the event to listen to; the second parameter is the function that handles this event; and the third parameter is an optional parameter that allows you to set more <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#parameters\">options for the listener</a>.</p><p>In most cases, you only need to use the first two parameters. Here's an example of handling the <code class=\"language-text\">click</code> event on a button:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">const</span> button <span class=\"token operator\">=</span> document<span class=\"token punctuation\">.</span><span class=\"token function\">querySelector</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"button\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\nbutton<span class=\"token punctuation\">.</span><span class=\"token function\">addEventListener</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"click\"</span><span class=\"token punctuation\">,</span> <span class=\"token keyword\">function</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">e</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token function\">alert</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Button clicked\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div><p>This retrieves the first button on the page and, when the button is clicked, shows an alert.</p><figure class=\"kg-card kg-image-card\"><img src=\"https://backend.shahednasser.com/content/images/2022/08/Screen-Shot-2022-08-10-at-9.39.02-PM.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"880\" height=\"252\" srcset=\"https://backend.shahednasser.com/content/images/size/w600/2022/08/Screen-Shot-2022-08-10-at-9.39.02-PM.png 600w, https://backend.shahednasser.com/content/images/2022/08/Screen-Shot-2022-08-10-at-9.39.02-PM.png 880w\" sizes=\"(min-width: 720px) 720px\"></figure><h3 id=\"can-an-event-have-more-than-one-handler\">Can an Event Have More Than One Handler?</h3><p>The same event can have many handlers. The handlers are triggered one by one when the event occurs.</p><h3 id=\"event-object\">Event Object</h3><p>As you can see, the function passed as a second parameter to <code class=\"language-text\">addEventListener</code> received the argument <code class=\"language-text\">e</code>. This is an <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Event\">Event</a> object. This object may have different properties depending on its underlying type. However, it has some common important properties.</p><p>A frequently used property on the Event object is the <code class=\"language-text\">target</code> property. This is the element that the event was triggered on. This can be helpful when you have the same handler for more than one element.</p><p>For example:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\">document<span class=\"token punctuation\">.</span><span class=\"token function\">querySelector</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"input\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">addEventListener</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"change\"</span><span class=\"token punctuation\">,</span> <span class=\"token keyword\">function</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">e</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token function\">alert</span><span class=\"token punctuation\">(</span>e<span class=\"token punctuation\">.</span>target<span class=\"token punctuation\">.</span>value<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div><p>This code snippet adds an event handler to the first <code class=\"language-text\">input</code> element on the <code class=\"language-text\">change</code> event. The <code class=\"language-text\">change</code> event is triggered when you change the value of the input, then move the focus from the input (for example, click on something else on the page).</p><p>When the <code class=\"language-text\">change</code> event occurs and the handler is triggered, the value of the input is retrieved using <code class=\"language-text\">e.target.value</code> and used in an alert.</p><h3 id=\"prevent-default-behavior-of-the-event\">Prevent Default Behavior of the Event</h3><p>In some cases, you want to prevent the default behavior of certain events. For example, when a link is clicked on a page, you might want to show a confirmation message before the user is actually taken to a new page.</p><p>To prevent the default behavior of an event, you can use the <code class=\"language-text\">preventDefault()</code> method on the Event object.</p><p>For example:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">const</span> a <span class=\"token operator\">=</span> document<span class=\"token punctuation\">.</span><span class=\"token function\">querySelector</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"a.some-link\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\na<span class=\"token punctuation\">.</span><span class=\"token function\">addEventListener</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"click\"</span><span class=\"token punctuation\">,</span> <span class=\"token keyword\">function</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">e</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    e<span class=\"token punctuation\">.</span><span class=\"token function\">preventDefault</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span><span class=\"token function\">confirm</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Are you sure?\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n      window<span class=\"token punctuation\">.</span>location<span class=\"token punctuation\">.</span>href <span class=\"token operator\">=</span> e<span class=\"token punctuation\">.</span>target<span class=\"token punctuation\">.</span>href<span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div><p>This adds an event handler to the <code class=\"language-text\">click</code> events on a link that has the class <code class=\"language-text\">some-link</code>. In the event handler, <code class=\"language-text\">e.preventDefault()</code> is used to prevent the default behavior of opening the page indicated in the <code class=\"language-text\">href</code> attribute.</p><p>It then shows the user a confirmation window, and if the user clicks Yes on the confirmation window, it then opens the page as expected.</p><h3 id=\"prevent-other-handlers-from-handling-this-event\">Prevent Other Handlers from Handling this Event</h3><p>As mentioned earlier, an event can have more than one handler. However, in some cases, you might want to cancel other events from handling this event. For example, if a request is sent to the server on form submission and you don't want other event handlers of form submission to send more requests.</p><p>There are two methods that can be used to prevent other handlers from handling the same event: <code class=\"language-text\">stopPropagation</code> and <code class=\"language-text\">stopImmediatePropagation</code>.</p><p><code class=\"language-text\">stopPropagation</code> is used to prevent other event handlers from handling an event during the bubbling phase. </p><p>Bubbling is when you have the same event on both child and parent elements. The event will be triggered first on the child element, then \"bubbled\" to the parent element.</p><p>In this case, <code class=\"language-text\">stopPropagation</code> prevents the event from being triggered on the parent element if called in the handler of the child element. However, it does not prevent the event from propagating to other event handlers.</p><p>To prevent the event from being handled by subsequent handlers, you can use <code class=\"language-text\">stopImmediatePropagation</code>.</p><p>For example:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">const</span> button <span class=\"token operator\">=</span> document<span class=\"token punctuation\">.</span><span class=\"token function\">querySelector</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"button\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\nbutton<span class=\"token punctuation\">.</span><span class=\"token function\">addEventListener</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"click\"</span><span class=\"token punctuation\">,</span> <span class=\"token keyword\">function</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">e</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  e<span class=\"token punctuation\">.</span><span class=\"token function\">stopImmediatePropagation</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token function\">alert</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Hello!\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\nbutton<span class=\"token punctuation\">.</span><span class=\"token function\">addEventListener</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"click\"</span><span class=\"token punctuation\">,</span> <span class=\"token keyword\">function</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">e</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token function\">alert</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Bye!\"</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span></code></pre></div><p>Although the button has two event handlers that listen to the <code class=\"language-text\">click</code> event, only the first one will run since it calls the <code class=\"language-text\">stopImmediatePropagation</code> function.</p><h3 id=\"difference-between-preventdefault-stoppropagation-and-stopimmediatepropagation\">Difference Between preventDefault, stopPropagation, and stopImmediatePropagation</h3><p><code class=\"language-text\">preventDefault</code> only prevents the default behavior of the event. However, it does not prevent other handlers from handling the event.</p><p><code class=\"language-text\">stopPropagation</code> and <code class=\"language-text\">stopImmediatePropagation</code> only prevent other handlers from handling the event. However, they don't prevent the default behavior of the event.</p><p>If you want to prevent both the default behavior and other handlers from handling the event, use <code class=\"language-text\">preventDefault</code> with either <code class=\"language-text\">stopPropagation</code> or <code class=\"language-text\">stopImmediatePropagation</code>.</p><h3 id=\"handle-events-on-dynamic-elements\">Handle Events on Dynamic Elements</h3><p>Consider the following example:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">const</span> buttons <span class=\"token operator\">=</span> document<span class=\"token punctuation\">.</span><span class=\"token function\">querySelectorAll</span><span class=\"token punctuation\">(</span><span class=\"token string\">\".btn\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\nbuttons<span class=\"token punctuation\">.</span><span class=\"token function\">forEach</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">btn</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  btn<span class=\"token punctuation\">.</span><span class=\"token function\">addEventListener</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"click\"</span><span class=\"token punctuation\">,</span> <span class=\"token keyword\">function</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">e</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token function\">alert</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Hello!\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n\n<span class=\"token comment\">//create new button</span>\n<span class=\"token keyword\">const</span> button <span class=\"token operator\">=</span> document<span class=\"token punctuation\">.</span><span class=\"token function\">createElement</span><span class=\"token punctuation\">(</span><span class=\"token string\">'button'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\nbutton<span class=\"token punctuation\">.</span>classList<span class=\"token punctuation\">.</span><span class=\"token function\">add</span><span class=\"token punctuation\">(</span><span class=\"token string\">'btn'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\nbutton<span class=\"token punctuation\">.</span>textContent <span class=\"token operator\">=</span> <span class=\"token string\">\"Bye\"</span><span class=\"token punctuation\">;</span>\ndocument<span class=\"token punctuation\">.</span>body<span class=\"token punctuation\">.</span><span class=\"token function\">append</span><span class=\"token punctuation\">(</span>button<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div><p>In this example, you first retrieve all buttons that have the class <code class=\"language-text\">btn</code>. Then, you loop over these buttons and add an event listener that just shows the alert \"Hello\" when the button is clicked.</p><p>Then, you dynamically create a new button, add the class <code class=\"language-text\">btn</code> to that button, and add it to the <code class=\"language-text\">body</code> of the document.</p><p>If you try clicking buttons that were added in the HTML of the document or that were added prior to adding the event listener, the alert will be shown as expected. However, if you click on the new button, no alert will be shown. </p><p>This is because the element was not part of the elements retrieved using <code class=\"language-text\">querySelectorAll</code> as it didn't exist at the time.</p><p>Although this is a reasonable outcome, in larger websites, you might not be able to attach an event handler every time you create a new element, or you might want to ensure that the event handler is added to all elements, whether originally or dynamically created, similarly.</p><p>In that case, instead of adding the event handler directly to each element separately, you can add the event handler to the document's <code class=\"language-text\">body</code> and use <code class=\"language-text\">e.target</code> to check if the element triggered matches a specific condition.</p><p>For example, you can transform the previous example to the following:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\">document<span class=\"token punctuation\">.</span>body<span class=\"token punctuation\">.</span><span class=\"token function\">addEventListener</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"click\"</span><span class=\"token punctuation\">,</span> <span class=\"token keyword\">function</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">e</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>e<span class=\"token punctuation\">.</span>target<span class=\"token punctuation\">.</span>classList<span class=\"token punctuation\">.</span><span class=\"token function\">contains</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"btn\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token function\">alert</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Hello!\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n\n<span class=\"token comment\">//create new button</span>\n<span class=\"token keyword\">const</span> button <span class=\"token operator\">=</span> document<span class=\"token punctuation\">.</span><span class=\"token function\">createElement</span><span class=\"token punctuation\">(</span><span class=\"token string\">'button'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\nbutton<span class=\"token punctuation\">.</span>classList<span class=\"token punctuation\">.</span><span class=\"token function\">add</span><span class=\"token punctuation\">(</span><span class=\"token string\">'btn'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\nbutton<span class=\"token punctuation\">.</span>textContent <span class=\"token operator\">=</span> <span class=\"token string\">\"Bye\"</span><span class=\"token punctuation\">;</span>\ndocument<span class=\"token punctuation\">.</span>body<span class=\"token punctuation\">.</span><span class=\"token function\">append</span><span class=\"token punctuation\">(</span>button<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div><p>You add a handler to the <code class=\"language-text\">click</code> event on the <code class=\"language-text\">body</code>. In the handler, you check if <code class=\"language-text\">e.target</code> has the class <code class=\"language-text\">btn</code> and only perform the necessary action if it does.</p><p>Now, when any of the elements that have the class <code class=\"language-text\">btn</code>, whether dynamically or initially created, are clicked, the event handler will run for them.</p><p>This approach, however, will run the event listener on every click event on the body. So, it's important to handle it based on the target carefully.</p><h2 id=\"remove-event-handler\">Remove Event Handler</h2><p>In some cases, you might want to remove an event handler for an element. To do that, you can use the <code class=\"language-text\">removeEventListener</code> method. This method is available on every Element and Node in the document.</p><p>This method receives the same parameters <code class=\"language-text\">addEventListener</code> receives. It's important to pass the same function that you passed to <code class=\"language-text\">addEventListener</code>. For that reason, people commonly define the function separately, then pass it to <code class=\"language-text\">addEventListener</code> and <code class=\"language-text\">removeEventListener</code>.</p><p>For example:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">const</span> button <span class=\"token operator\">=</span> document<span class=\"token punctuation\">.</span><span class=\"token function\">querySelector</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"button\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token keyword\">function</span> <span class=\"token function\">handleClick</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">e</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token function\">alert</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Hello\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span>\n\nbutton<span class=\"token punctuation\">.</span><span class=\"token function\">addEventListener</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"click\"</span><span class=\"token punctuation\">,</span> handleClick<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token comment\">//some time later</span>\nbutton<span class=\"token punctuation\">.</span><span class=\"token function\">removeEventListener</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"click\"</span><span class=\"token punctuation\">,</span> handleClick<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div><h2 id=\"conclusion\">Conclusion</h2><p>This article scratches the surface of Events and helps you understand them better. To learn more about Events in JavaScript, check out the following resources:</p><ol><li><a href=\"https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Events\">Introduction to Events</a></li><li><a href=\"https://developer.mozilla.org/en-US/docs/Web/Events\">Event Reference</a></li></ol>","htmlAst":{"type":"root","children":[{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Events in JavaScript allow developers to listen for changes in the document and handle them as necessary. For example, you can listen to when a button is clicked to open a modal. Another example is showing the \"scroll up\" button when the user scrolls halfway through the page."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"This article helps beginners understand what Events are in JavaScript and how to handle them."}]},{"type":"element","tagName":"h2","properties":{"id":"why-use-events"},"children":[{"type":"text","value":"Why Use Events"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Modern websites have evolved to be interactive and reactive. Instead of presenting information or functionalities all at once, some can be shown to the user based on a specific action performed. The example mentioned earlier in the article illustrates this."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Events are also helpful in detecting different states of your website. For example, detecting when a screen is resized can help to ensure the responsiveness of certain elements on the page."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"The list of use cases where events are helpful is endless. Events are an essential part of web development with JavaScript and it's important to understand how to use them."}]},{"type":"element","tagName":"h2","properties":{"id":"add-event-handler"},"children":[{"type":"text","value":"Add Event Handler"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"To listen to events, you can use the "},{"type":"element","tagName":"a","properties":{"href":"https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener"},"children":[{"type":"text","value":"addEventListener"}]},{"type":"text","value":" method. This method is available on every Element and Node in the document."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"addEventListener"}]},{"type":"text","value":" accepts three parameters: the first parameter is the name of the event to listen to; the second parameter is the function that handles this event; and the third parameter is an optional parameter that allows you to set more "},{"type":"element","tagName":"a","properties":{"href":"https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#parameters"},"children":[{"type":"text","value":"options for the listener"}]},{"type":"text","value":"."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"In most cases, you only need to use the first two parameters. Here's an example of handling the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"click"}]},{"type":"text","value":" event on a button:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" button "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" document"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"querySelector"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"button\""}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\nbutton"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"addEventListener"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"click\""}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"function"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"e"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"alert"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"Button clicked\""}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"This retrieves the first button on the page and, when the button is clicked, shows an alert."}]},{"type":"element","tagName":"figure","properties":{"className":["kg-card","kg-image-card"]},"children":[{"type":"element","tagName":"img","properties":{"src":"https://backend.shahednasser.com/content/images/2022/08/Screen-Shot-2022-08-10-at-9.39.02-PM.png","className":["kg-image"],"alt":"","loading":"lazy","width":880,"height":252,"srcSet":["https://backend.shahednasser.com/content/images/size/w600/2022/08/Screen-Shot-2022-08-10-at-9.39.02-PM.png 600w","https://backend.shahednasser.com/content/images/2022/08/Screen-Shot-2022-08-10-at-9.39.02-PM.png 880w"],"sizes":"(min-width: 720px) 720px"},"children":[]}]},{"type":"element","tagName":"h3","properties":{"id":"can-an-event-have-more-than-one-handler"},"children":[{"type":"text","value":"Can an Event Have More Than One Handler?"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"The same event can have many handlers. The handlers are triggered one by one when the event occurs."}]},{"type":"element","tagName":"h3","properties":{"id":"event-object"},"children":[{"type":"text","value":"Event Object"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"As you can see, the function passed as a second parameter to "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"addEventListener"}]},{"type":"text","value":" received the argument "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"e"}]},{"type":"text","value":". This is an "},{"type":"element","tagName":"a","properties":{"href":"https://developer.mozilla.org/en-US/docs/Web/API/Event"},"children":[{"type":"text","value":"Event"}]},{"type":"text","value":" object. This object may have different properties depending on its underlying type. However, it has some common important properties."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"A frequently used property on the Event object is the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"target"}]},{"type":"text","value":" property. This is the element that the event was triggered on. This can be helpful when you have the same handler for more than one element."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"For example:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"text","value":"document"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"querySelector"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"input\""}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"addEventListener"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"change\""}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"function"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"e"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"alert"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"e"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"target"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"value"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"This code snippet adds an event handler to the first "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"input"}]},{"type":"text","value":" element on the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"change"}]},{"type":"text","value":" event. The "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"change"}]},{"type":"text","value":" event is triggered when you change the value of the input, then move the focus from the input (for example, click on something else on the page)."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"When the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"change"}]},{"type":"text","value":" event occurs and the handler is triggered, the value of the input is retrieved using "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"e.target.value"}]},{"type":"text","value":" and used in an alert."}]},{"type":"element","tagName":"h3","properties":{"id":"prevent-default-behavior-of-the-event"},"children":[{"type":"text","value":"Prevent Default Behavior of the Event"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"In some cases, you want to prevent the default behavior of certain events. For example, when a link is clicked on a page, you might want to show a confirmation message before the user is actually taken to a new page."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"To prevent the default behavior of an event, you can use the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"preventDefault()"}]},{"type":"text","value":" method on the Event object."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"For example:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" a "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" document"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"querySelector"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"a.some-link\""}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\na"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"addEventListener"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"click\""}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"function"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"e"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n    e"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"preventDefault"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"if"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"confirm"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"Are you sure?\""}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n      window"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"location"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"href "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" e"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"target"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"href"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"This adds an event handler to the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"click"}]},{"type":"text","value":" events on a link that has the class "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"some-link"}]},{"type":"text","value":". In the event handler, "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"e.preventDefault()"}]},{"type":"text","value":" is used to prevent the default behavior of opening the page indicated in the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"href"}]},{"type":"text","value":" attribute."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"It then shows the user a confirmation window, and if the user clicks Yes on the confirmation window, it then opens the page as expected."}]},{"type":"element","tagName":"h3","properties":{"id":"prevent-other-handlers-from-handling-this-event"},"children":[{"type":"text","value":"Prevent Other Handlers from Handling this Event"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"As mentioned earlier, an event can have more than one handler. However, in some cases, you might want to cancel other events from handling this event. For example, if a request is sent to the server on form submission and you don't want other event handlers of form submission to send more requests."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"There are two methods that can be used to prevent other handlers from handling the same event: "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"stopPropagation"}]},{"type":"text","value":" and "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"stopImmediatePropagation"}]},{"type":"text","value":"."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"stopPropagation"}]},{"type":"text","value":" is used to prevent other event handlers from handling an event during the bubbling phase. "}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Bubbling is when you have the same event on both child and parent elements. The event will be triggered first on the child element, then \"bubbled\" to the parent element."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"In this case, "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"stopPropagation"}]},{"type":"text","value":" prevents the event from being triggered on the parent element if called in the handler of the child element. However, it does not prevent the event from propagating to other event handlers."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"To prevent the event from being handled by subsequent handlers, you can use "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"stopImmediatePropagation"}]},{"type":"text","value":"."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"For example:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" button "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" document"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"querySelector"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"button\""}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n\nbutton"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"addEventListener"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"click\""}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"function"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"e"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n  e"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"stopImmediatePropagation"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"alert"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"Hello!\""}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n\nbutton"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"addEventListener"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"click\""}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"function"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"e"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"alert"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"Bye!\""}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Although the button has two event handlers that listen to the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"click"}]},{"type":"text","value":" event, only the first one will run since it calls the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"stopImmediatePropagation"}]},{"type":"text","value":" function."}]},{"type":"element","tagName":"h3","properties":{"id":"difference-between-preventdefault-stoppropagation-and-stopimmediatepropagation"},"children":[{"type":"text","value":"Difference Between preventDefault, stopPropagation, and stopImmediatePropagation"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"preventDefault"}]},{"type":"text","value":" only prevents the default behavior of the event. However, it does not prevent other handlers from handling the event."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"stopPropagation"}]},{"type":"text","value":" and "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"stopImmediatePropagation"}]},{"type":"text","value":" only prevent other handlers from handling the event. However, they don't prevent the default behavior of the event."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"If you want to prevent both the default behavior and other handlers from handling the event, use "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"preventDefault"}]},{"type":"text","value":" with either "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"stopPropagation"}]},{"type":"text","value":" or "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"stopImmediatePropagation"}]},{"type":"text","value":"."}]},{"type":"element","tagName":"h3","properties":{"id":"handle-events-on-dynamic-elements"},"children":[{"type":"text","value":"Handle Events on Dynamic Elements"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Consider the following example:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" buttons "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" document"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"querySelectorAll"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\".btn\""}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n\nbuttons"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"forEach"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"btn"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n  btn"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"addEventListener"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"click\""}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"function"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"e"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"alert"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"Hello!\""}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"//create new button"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" button "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" document"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"createElement"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'button'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\nbutton"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"classList"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"add"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'btn'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\nbutton"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"textContent "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"Bye\""}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\ndocument"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"body"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"append"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"button"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"In this example, you first retrieve all buttons that have the class "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"btn"}]},{"type":"text","value":". Then, you loop over these buttons and add an event listener that just shows the alert \"Hello\" when the button is clicked."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Then, you dynamically create a new button, add the class "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"btn"}]},{"type":"text","value":" to that button, and add it to the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"body"}]},{"type":"text","value":" of the document."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"If you try clicking buttons that were added in the HTML of the document or that were added prior to adding the event listener, the alert will be shown as expected. However, if you click on the new button, no alert will be shown. "}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"This is because the element was not part of the elements retrieved using "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"querySelectorAll"}]},{"type":"text","value":" as it didn't exist at the time."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Although this is a reasonable outcome, in larger websites, you might not be able to attach an event handler every time you create a new element, or you might want to ensure that the event handler is added to all elements, whether originally or dynamically created, similarly."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"In that case, instead of adding the event handler directly to each element separately, you can add the event handler to the document's "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"body"}]},{"type":"text","value":" and use "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"e.target"}]},{"type":"text","value":" to check if the element triggered matches a specific condition."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"For example, you can transform the previous example to the following:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"text","value":"document"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"body"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"addEventListener"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"click\""}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"function"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"e"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"if"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"e"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"target"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"classList"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"contains"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"btn\""}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"alert"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"Hello!\""}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"//create new button"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" button "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" document"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"createElement"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'button'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\nbutton"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"classList"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"add"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'btn'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\nbutton"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"textContent "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"Bye\""}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\ndocument"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"body"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"append"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"button"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"You add a handler to the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"click"}]},{"type":"text","value":" event on the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"body"}]},{"type":"text","value":". In the handler, you check if "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"e.target"}]},{"type":"text","value":" has the class "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"btn"}]},{"type":"text","value":" and only perform the necessary action if it does."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Now, when any of the elements that have the class "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"btn"}]},{"type":"text","value":", whether dynamically or initially created, are clicked, the event handler will run for them."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"This approach, however, will run the event listener on every click event on the body. So, it's important to handle it based on the target carefully."}]},{"type":"element","tagName":"h2","properties":{"id":"remove-event-handler"},"children":[{"type":"text","value":"Remove Event Handler"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"In some cases, you might want to remove an event handler for an element. To do that, you can use the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"removeEventListener"}]},{"type":"text","value":" method. This method is available on every Element and Node in the document."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"This method receives the same parameters "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"addEventListener"}]},{"type":"text","value":" receives. It's important to pass the same function that you passed to "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"addEventListener"}]},{"type":"text","value":". For that reason, people commonly define the function separately, then pass it to "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"addEventListener"}]},{"type":"text","value":" and "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"removeEventListener"}]},{"type":"text","value":"."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"For example:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" button "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" document"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"querySelector"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"button\""}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"function"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"handleClick"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"e"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"alert"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"Hello\""}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n\nbutton"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"addEventListener"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"click\""}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" handleClick"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"//some time later"}]},{"type":"text","value":"\nbutton"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"removeEventListener"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"click\""}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" handleClick"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]}]}]}]},{"type":"element","tagName":"h2","properties":{"id":"conclusion"},"children":[{"type":"text","value":"Conclusion"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"This article scratches the surface of Events and helps you understand them better. To learn more about Events in JavaScript, check out the following resources:"}]},{"type":"element","tagName":"ol","properties":{},"children":[{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"a","properties":{"href":"https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Events"},"children":[{"type":"text","value":"Introduction to Events"}]}]},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"a","properties":{"href":"https://developer.mozilla.org/en-US/docs/Web/Events"},"children":[{"type":"text","value":"Event Reference"}]}]}]}],"data":{"quirksMode":false}},"tableOfContents":[{"id":"why-use-events","heading":"Why Use Events"},{"id":"add-event-handler","heading":"Add Event Handler","items":[{"id":"can-an-event-have-more-than-one-handler","heading":"Can an Event Have More Than One Handler?"},{"id":"event-object","heading":"Event Object"},{"id":"prevent-default-behavior-of-the-event","heading":"Prevent Default Behavior of the Event"},{"id":"prevent-other-handlers-from-handling-this-event","heading":"Prevent Other Handlers from Handling this Event"},{"id":"difference-between-preventdefault-stoppropagation-and-stopimmediatepropagation","heading":"Difference Between preventDefault, stopPropagation, and stopImmediatePropagation"},{"id":"handle-events-on-dynamic-elements","heading":"Handle Events on Dynamic Elements"}]},{"id":"remove-event-handler","heading":"Remove Event Handler"},{"id":"conclusion","heading":"Conclusion"}]},"featureImageSharp":{"base":"Events-in-JavaScript-3.jpg","publicURL":"/static/c3e7617caba682aec0dbfe3b6d2bbd87/Events-in-JavaScript-3.jpg","imageMeta":{"width":1560,"height":876},"childImageSharp":{"fluid":{"base64":"data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAALABQDASIAAhEBAxEB/8QAGAAAAwEBAAAAAAAAAAAAAAAAAAIDBAX/xAAVAQEBAAAAAAAAAAAAAAAAAAAAAf/aAAwDAQACEAMQAAAB7cdSwhQr/8QAGRAAAwEBAQAAAAAAAAAAAAAAAQIDABIi/9oACAEBAAEFAvWrXhpN1PFQ2ACj/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPwE//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPwE//8QAGRABAQEAAwAAAAAAAAAAAAAAAQARECEx/9oACAEBAAY/AoM9h47LC//EABwQAAMAAQUAAAAAAAAAAAAAAAABERAhMUGBkf/aAAgBAQABPyF6nJ6VhonBQr3japiwiJH/2gAMAwEAAgADAAAAEK8P/8QAFhEBAQEAAAAAAAAAAAAAAAAAARBR/9oACAEDAQE/EB2f/8QAFxEAAwEAAAAAAAAAAAAAAAAAARARQf/aAAgBAgEBPxA3F//EABsQAQADAQEBAQAAAAAAAAAAAAEAESFBMVHh/9oACAEBAAE/EBk1vL/ER9o0DvKibKlLW2svPsAG5xn8s8gFhUByf//Z","aspectRatio":1.7857142857142858,"src":"/static/c3e7617caba682aec0dbfe3b6d2bbd87/ea4ab/Events-in-JavaScript-3.jpg","srcSet":"/static/c3e7617caba682aec0dbfe3b6d2bbd87/477ba/Events-in-JavaScript-3.jpg 175w,\n/static/c3e7617caba682aec0dbfe3b6d2bbd87/06776/Events-in-JavaScript-3.jpg 350w,\n/static/c3e7617caba682aec0dbfe3b6d2bbd87/ea4ab/Events-in-JavaScript-3.jpg 700w,\n/static/c3e7617caba682aec0dbfe3b6d2bbd87/3055e/Events-in-JavaScript-3.jpg 1050w,\n/static/c3e7617caba682aec0dbfe3b6d2bbd87/eff08/Events-in-JavaScript-3.jpg 1400w,\n/static/c3e7617caba682aec0dbfe3b6d2bbd87/81a53/Events-in-JavaScript-3.jpg 1560w","srcWebp":"/static/c3e7617caba682aec0dbfe3b6d2bbd87/89afa/Events-in-JavaScript-3.webp","srcSetWebp":"/static/c3e7617caba682aec0dbfe3b6d2bbd87/9fca7/Events-in-JavaScript-3.webp 175w,\n/static/c3e7617caba682aec0dbfe3b6d2bbd87/37a4e/Events-in-JavaScript-3.webp 350w,\n/static/c3e7617caba682aec0dbfe3b6d2bbd87/89afa/Events-in-JavaScript-3.webp 700w,\n/static/c3e7617caba682aec0dbfe3b6d2bbd87/78e7a/Events-in-JavaScript-3.webp 1050w,\n/static/c3e7617caba682aec0dbfe3b6d2bbd87/03d34/Events-in-JavaScript-3.webp 1400w,\n/static/c3e7617caba682aec0dbfe3b6d2bbd87/f5845/Events-in-JavaScript-3.webp 1560w","sizes":"(max-width: 700px) 100vw, 700px"}}}},"next":{"id":"Ghost__Post__62d068d44e918d05f353772c","title":"Beginner's Guide to Kubernetes: Understand the Basics","slug":"beginners-guide-to-kubernetes-understand-the-basics","featured":true,"feature_image":"https://backend.shahednasser.com/content/images/2022/07/Beginner-s-Guide-to-Kubernetes--Understand-the-Basics.jpg","excerpt":"In this blog, we will discuss what they are, how they are used, what is the workflow they have, and whether every application needs it.","custom_excerpt":"In this blog, we will discuss what they are, how they are used, what is the workflow they have, and whether every application needs it.","visibility":"public","created_at_pretty":"14 Jul 2022","published_at_pretty":"14 Jul 2022","updated_at_pretty":"15 Jul 2022","created_at":"2022-07-14T19:04:52.000+00:00","published_at":"2022-07-14T19:14:54.000+00:00","updated_at":"2022-07-15T19:28:34.000+00:00","meta_title":null,"meta_description":null,"og_description":null,"og_image":null,"og_title":null,"twitter_description":null,"twitter_image":null,"twitter_title":null,"authors":[{"slug":"shajith","url":"https://backend.shahednasser.com/author/shajith/","name":"Shajith","bio":"A front-end developer and DevOps engineer","cover_image":null,"profile_image":"https://backend.shahednasser.com/content/images/2022/07/profile-picture.png","location":null,"website":"http://blog.shajith.co.in","twitter":"@Shajith_it_is","facebook":null,"meta_title":null,"meta_description":null,"coverImageSharp":null,"profileImageSharp":null}],"primary_author":{"slug":"shajith","url":"https://backend.shahednasser.com/author/shajith/","name":"Shajith","bio":"A front-end developer and DevOps engineer","cover_image":null,"profile_image":"https://backend.shahednasser.com/content/images/2022/07/profile-picture.png","location":null,"website":"http://blog.shajith.co.in","twitter":"@Shajith_it_is","facebook":null,"meta_title":null,"meta_description":null,"coverImageSharp":null,"profileImageSharp":{"base":"profile-picture.png","publicURL":"/static/f39e19f31e03b69fa4f0a29a39873f42/profile-picture.png","imageMeta":{"width":316,"height":400},"childImageSharp":{"fluid":{"base64":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAZCAIAAAC+dZmEAAAACXBIWXMAAAsTAAALEwEAmpwYAAAD00lEQVQ4y5WTfUwbdRjH+dMYlSxDVluwkOK2UDZwZiaaaB3TJf5rHEuLDJhxcTO+Zoka/xkTZQwd020R1vaud3253v3u2utKGSBkg/V+d31/XWGsQd3sXVspUBP/N5SFsTLnlnzz5Pd78nzyJN/neSp4E10miAKIAr/ZGbK6/LjThztWMyawubKi7O81kn7cGTCz7rND1m8HRs5dGjuPCJhDwBgOoR4GcygVsl6mT//UpnnjxbraJoVsr6r+pXrloX2tExdNftxRxldsJMM2t+XUQItSodpa2SivVsu3NT63Gp+vfFLbuj9KeAJmFqKgHIYoEDBmxkC0Nu9uqNrSXKtoUsiaa+Vq+bYmhUwtl+2ornrvzbfGL6B+s3OdvwcHLax7cLhFWbOrRtaiVJQaPvNyQ92euprX1C+8rt6ueOoJ7b79G5vfhTmEihAjw1+f3FFdtbtWrtq65dWdqlPHdNN4v6Hn42vYac2u7Ttlz+5V1U/9gvtL/t8Hx0hP//Ev9tTXdL2t+fCdA1fx/n9irpUgM3vlktf+48HWV5SVT2vUjTMGQsCY+2CIgrDNbe0989G7B5LuIWg/e2fanINEnrenf0V4ajDKXtQ0NXzWpouRo+ue33MbIkyMJqLs+TxvD7MXbk0Yl/xgKUAvTKFB5ueCj+JsZzjc6MNZ3gQ2jQqhYwAsBUAOEsUQU/BR6QnD/Lj+L4H8O+TIQWIlSKdYxmsEPPagJfEa6Tk3ueizSxyRhfZ82JULsXkBSJxt0WefHyW8RiBg/7VhCB0m6BxPFEP0FaRP39uD9PWOIv3FEJ3niSi1WvCw3eYQet5DLgep29Pmqa8+nzzxyW+T6EqISo+REP2/w1g1AwNzbnvmumU54liJOkWv9abHLuCA33RYmzuzXgPLY46kBwlQ53zkYNQ1xGOM1+CCyJrP4AEwRB0QcUZofWq8R7zJFcIjWa9Z8poLQVacnZkdPxlhhiHigIijbFQAooyAk7eufSMlDmeTB4vLNwqzoTxH5jmykBSKS/Fssk1KdqSvf+mzEOt8CUZpHgML3IlsSivGuzMRXS79w+IfQAp8J/m/X1yw5dIDmYhOjHVnU7rfhU8FnIQoU4IxwBldqbG+bEqbiXaL8U4x3pmJtWeih8REu5hoz8TaMjHd3Xz0SDalnZvs4Ywsj4EK3sQIGHU7cFxKdoixrrUiMd4lxrtLcf2xlu+UEh13Qkd9ZgKiTAVEnEE7KiUOS4mOR1T2RnsY6DmELcEkkom8/2f4g0fT0Uz0SJjWc4izZBgG/BbbY4nHNtwzjzKPp9Kc/wXVp8k7wW5pDgAAAABJRU5ErkJggg==","aspectRatio":0.8,"src":"/static/f39e19f31e03b69fa4f0a29a39873f42/6ccb0/profile-picture.png","srcSet":"/static/f39e19f31e03b69fa4f0a29a39873f42/7d89d/profile-picture.png 28w,\n/static/f39e19f31e03b69fa4f0a29a39873f42/f4091/profile-picture.png 55w,\n/static/f39e19f31e03b69fa4f0a29a39873f42/6ccb0/profile-picture.png 110w,\n/static/f39e19f31e03b69fa4f0a29a39873f42/30481/profile-picture.png 165w,\n/static/f39e19f31e03b69fa4f0a29a39873f42/33bd6/profile-picture.png 220w,\n/static/f39e19f31e03b69fa4f0a29a39873f42/d398b/profile-picture.png 316w","srcWebp":"/static/f39e19f31e03b69fa4f0a29a39873f42/8678c/profile-picture.webp","srcSetWebp":"/static/f39e19f31e03b69fa4f0a29a39873f42/59cda/profile-picture.webp 28w,\n/static/f39e19f31e03b69fa4f0a29a39873f42/7da75/profile-picture.webp 55w,\n/static/f39e19f31e03b69fa4f0a29a39873f42/8678c/profile-picture.webp 110w,\n/static/f39e19f31e03b69fa4f0a29a39873f42/f282e/profile-picture.webp 165w,\n/static/f39e19f31e03b69fa4f0a29a39873f42/a7b21/profile-picture.webp 220w,\n/static/f39e19f31e03b69fa4f0a29a39873f42/fb2b8/profile-picture.webp 316w","sizes":"(max-width: 110px) 100vw, 110px"}}}},"primary_tag":{"slug":"kubernetes","url":"https://backend.shahednasser.com/tag/kubernetes/","name":"Kubernetes","visibility":"public","feature_image":null,"description":null,"meta_title":null,"meta_description":null,"featureImageSharp":null},"tags":[{"slug":"kubernetes","url":"https://backend.shahednasser.com/tag/kubernetes/","name":"Kubernetes","visibility":"public","feature_image":null,"description":null,"meta_title":null,"meta_description":null,"featureImageSharp":null}],"plaintext":"You probably have heard the term Kubernetes, somewhere or the other. K8S is an abbreviated form for Kubernetes, starting with the letter ‘K’, Ending with ‘S’, and has 8 characters between the letters, hence the name.\n\nIn this blog, we will discuss what they are, how they are used, what is the workflow they have, and whether every application needs it.\n\n\nWhat is Kubernetes?\n\nKubernetes is an open-source project initially developed by Google. It is a container orchestration tool. It can be used using on-premise systems, VMs, and clouds.\n\nKubernetes is also provided as a service by many providers like AWS, Azure, and Google, and they are known as Amazon EKS, AKS, and GKE respectively. Each has its specific features.\n\nI get it, if you were to ask what container orchestration is, Let’s see in short what that means,\n\n\nMoving your Application to the Internet\n\nYou have an application on your machine that you want to deploy to the internet. Let’s say that it is Irrespective of what framework you use, or it is just the html, CSS, and js, you may want to host it on a server and map it with a domain.\n\nOne of the most common ways to do that is to use a VM and copy those files over there, use Nginx or apache or anything of your preference, start a server, and map the server with a domain name.\n\n\nVirtual Machines\n\nVM is one of the first choices in hosting your applications for specific cases. Now, hoping your web application gets popular, how much do you think a VM can accommodate on its server? A VM is simply a computer, RAM, ROM, CPU, etc resources are fixed.\n\nTo imagine, you can think of the number of people who can use your computer simultaneously. Likewise, how will the performance be when so many users access the website at the same time? And this is dependent on the resources of the machine.\n\nIf you have higher resources, it can accommodate a lot of users and less if it has lesser resources.\n\nThese are some of the questions that arise when a website is moved to production, including how many resources you need in your case, which shows higher performance, etc... Setting up a new VM is costly since it is almost an independent machine like the one you're building these with.\n\nAlso, it is a tedious task to create, monitor, and manage multiple instances of the same and redirect them if one is busy.\n\nThese are a few problems that may arise when on a VM. Since a VM is a complete structure, it has numerous packages, OS, and many other dependencies, which are irrelevant for the application to run. Also, the resources can not be used effectively since there is no proper allocation and utilization. That is where containers arise.\n\n\nContainers\n\nContainers are executable software applications that contain everything it needs to run on their own. Unlike VM, containers are smaller packages and so transporting them is easier. They can also be increased in number or decreased effortlessly. This is one of the important aspects of Kubernetes.\n\nIn an application, there can be several micro-services that help the function of the app. In that case, every micro-service will be made as a container and you can see from this that, as the complexity and size of the application increases, you have to manage multiple containers. Here is where Kubernetes comes in.\n\n\nContainer Orchestration tool\n\nKubernetes is a container orchestration tool, which means you get to increase, decrease, destroy, create, and configure containers with higher specifications and much more.\n\nThese help in scalability, monitoring, Health-checks and many more. Let’s see a real-time example of how container orchestration helps.\n\n\nShort overview of a Real-time application\n\nYou developed a full-stack application. It will probably have a Front-end facing application, a backend, and a database.\n\nDatabases should be configured to be updated simultaneously in all the instances if we were to increase them in number, to avoid corruption of data, which again is not easier.\n\nA database can be deployed in Kubernetes as a stateful set, but that needs a few extra configurations. There are many other different approaches other than Kubernetes for databases. Here in this blog, we will just focus on the front-end and back-end.\n\n\nContainerizing the applications\n\nUsing docker you will probably have to create a docker file and write configurations in YAML so that the front-end can serve. Nginx or apache servers are generally used for front-end containers but there are many different ways as well. Similarly, a backend container is created.\n\nNow that you have a front-end container and a back-end container, you want to take the images of both containers and push them to an image repository.\n\n\nPushing the container images\n\nAn image repository is generally provided by the cloud provider but Docker has its repository as well, and there are many different other image repositories available, you can choose one of your choices.\n\nNow, you can add continuous integration and a continuous delivery pipeline in it and deliver the container images to Kubernetes or, you can send them to it directly as well. Continuous integration and continuous delivery pipeline is a different topic, you can learn about them separately and it is independent of Kubernetes.\n\nNow that the image is pushed to Kubernetes, the image will be built and the container will run.\n\nNow zooming out, let’s know some terms and structure of Kubernetes.\n\n\nStructure of Kubernetes and its terms\n\n\nWhat are Pods and Nodes in Kubernetes?\n\nA pod is a basic deployment on which your container runs. A pod can have multiple containers but generally, a pod per container is preferred.\n\nA node can be a physical machine or virtual machine and it is where the pods are deployed. A cluster can have several nodes on them.\n\nThe order is like this: container < pod < node < cluster.\n\nWe can start the pod by mentioning how many replicas we want, how many maximum replicas it can have, auto-scaling, health-check, etc.\n\nThe health-check feature checks whether a pod is healthy (running ) and if not, it will pass the information that can be made to create a new pod or inform the user about it for handling. So even if one pod fails, it will automatically detect it and can be made to create further replicas. This is mostly done with zero downtime.\n\n\nWhat is downtime?\n\nIt is the time duration, in which the server is neither accessible nor working.\n\nZero Downtime is something that is preferred everywhere. We all know how it is when the site we use most often is down for maintenance or because the server crashed.\n\nTo prevent this and enhance the user experience, Zero downtime is a requirement nowadays.\n\nKubernetes helps in 0 downtime - Until a healthy pod starts, the new pod will not destroy itself. This way during updates you can have zero downtime, and also if some pod fails, It can be made to create replicas, etc…\n\n\nWho needs Kubernetes?\n\nNot every application needs Kubernetes, that said every product can have Kubernetes with its features if required. Kubernetes can help your application in many different ways but you probably can analyze different problems like resource management, downtime issues, scaling issues, and feasibility.\n\nIf you need to monitor and automate a large number of containers (micro-services), Kubernetes comes in handy. It does have different other features, which in case required for your product, you can use Kubernetes.\n\n\nConclusion\n\nK8s is a container orchestration tool and it is used when there is an increased number of containers which can be difficult to monitor and handle. Not every application requires it, you can choose it if the features match your requirement.\n\nA pod is a basic deployment that can be configured using YAML, the containers are deployed on pods and these pods are located on nodes, where nodes are created on clusters. It is better to know all the features of Kubernetes and match them with your application requirements, before implementing it.\n\nFor a large-scale application, Kubernetes saves a lot of time and automates almost everything related to scaling and everything with zero downtime.","html":"<p>You probably have heard the term Kubernetes, somewhere or the other. K8S is an abbreviated form for Kubernetes, starting with the letter ‘K’, Ending with ‘S’, and has 8 characters between the letters, hence the name.</p><p>In this blog, we will discuss what they are, how they are used, what is the workflow they have, and whether every application needs it.</p><h2 id=\"what-is-kubernetes\">What is Kubernetes?</h2><p>Kubernetes is an open-source project initially developed by Google. It is a container orchestration tool. It can be used using on-premise systems, VMs, and clouds.</p><p>Kubernetes is also provided as a service by many providers like AWS, Azure, and Google, and they are known as Amazon EKS, AKS, and GKE respectively. Each has its specific features.</p><p>I get it, if you were to ask what container orchestration is, Let’s see in short what that means,</p><h3 id=\"moving-your-application-to-the-internet\">Moving your Application to the Internet</h3><p>You have an application on your machine that you want to deploy to the internet. Let’s say that it is Irrespective of what framework you use, or it is just the html, CSS, and js, you may want to host it on a server and map it with a domain.</p><p>One of the most common ways to do that is to use a VM and copy those files over there, use Nginx or apache or anything of your preference, start a server, and map the server with a domain name.</p><h3 id=\"virtual-machines\">Virtual Machines</h3><p>VM is one of the first choices in hosting your applications for specific cases. Now, hoping your web application gets popular, how much do you think a VM can accommodate on its server? A VM is simply a computer, RAM, ROM, CPU, etc resources are fixed.</p><p>To imagine, you can think of the number of people who can use your computer simultaneously. Likewise, how will the performance be when so many users access the website at the same time? And this is dependent on the resources of the machine.</p><p>If you have higher resources, it can accommodate a lot of users and less if it has lesser resources.</p><p>These are some of the questions that arise when a website is moved to production, including how many resources you need in your case, which shows higher performance, etc... Setting up a new VM is costly since it is almost an independent machine like the one you're building these with.</p><p>Also, it is a tedious task to create, monitor, and manage multiple instances of the same and redirect them if one is busy.</p><p>These are a few problems that may arise when on a VM. Since a VM is a complete structure, it has numerous packages, OS, and many other dependencies, which are irrelevant for the application to run. Also, the resources can not be used effectively since there is no proper allocation and utilization. That is where containers arise.</p><h3 id=\"containers\">Containers</h3><p>Containers are executable software applications that contain everything it needs to run on their own. Unlike VM, containers are smaller packages and so transporting them is easier. They can also be increased in number or decreased effortlessly. This is one of the important aspects of Kubernetes.</p><p>In an application, there can be several micro-services that help the function of the app. In that case, every micro-service will be made as a container and you can see from this that, as the complexity and size of the application increases, you have to manage multiple containers. Here is where Kubernetes comes in.</p><h3 id=\"container-orchestration-tool\">Container Orchestration tool</h3><p>Kubernetes is a container orchestration tool, which means you get to increase, decrease, destroy, create, and configure containers with higher specifications and much more.</p><p>These help in scalability, monitoring, Health-checks and many more. Let’s see a real-time example of how container orchestration helps.</p><h2 id=\"short-overview-of-a-real-time-application\">Short overview of a Real-time application</h2><p>You developed a full-stack application. It will probably have a Front-end facing application, a backend, and a database.</p><p>Databases should be configured to be updated simultaneously in all the instances if we were to increase them in number, to avoid corruption of data, which again is not easier.</p><p>A database can be deployed in Kubernetes as a stateful set, but that needs a few extra configurations. There are many other different approaches other than Kubernetes for databases. Here in this blog, we will just focus on the front-end and back-end.</p><h3 id=\"containerizing-the-applications\">Containerizing the applications</h3><p>Using docker you will probably have to create a docker file and write configurations in YAML so that the front-end can serve. Nginx or apache servers are generally used for front-end containers but there are many different ways as well. Similarly, a backend container is created.</p><p>Now that you have a front-end container and a back-end container, you want to take the images of both containers and push them to an image repository.</p><h3 id=\"pushing-the-container-images\">Pushing the container images</h3><p>An image repository is generally provided by the cloud provider but Docker has its repository as well, and there are many different other image repositories available, you can choose one of your choices.</p><p>Now, you can add continuous integration and a continuous delivery pipeline in it and deliver the container images to Kubernetes or, you can send them to it directly as well. Continuous integration and continuous delivery pipeline is a different topic, you can learn about them separately and it is independent of Kubernetes.</p><p>Now that the image is pushed to Kubernetes, the image will be built and the container will run.</p><p>Now zooming out, let’s know some terms and structure of Kubernetes.</p><h2 id=\"structure-of-kubernetes-and-its-terms\">Structure of Kubernetes and its terms</h2><h3 id=\"what-are-pods-and-nodes-in-kubernetes\">What are Pods and Nodes in Kubernetes?</h3><p>A pod is a basic deployment on which your container runs. A pod can have multiple containers but generally, a pod per container is preferred.</p><p>A node can be a physical machine or virtual machine and it is where the pods are deployed. A cluster can have several nodes on them.</p><p>The order is like this: container &lt; pod &lt; node &lt; cluster.</p><p>We can start the pod by mentioning how many replicas we want, how many maximum replicas it can have, auto-scaling, health-check, etc.</p><p>The health-check feature checks whether a pod is healthy (running ) and if not, it will pass the information that can be made to create a new pod or inform the user about it for handling. So even if one pod fails, it will automatically detect it and can be made to create further replicas. This is mostly done with zero downtime.</p><h3 id=\"what-is-downtime\">What is downtime?</h3><p>It is the time duration, in which the server is neither accessible nor working.</p><p>Zero Downtime is something that is preferred everywhere. We all know how it is when the site we use most often is down for maintenance or because the server crashed.</p><p>To prevent this and enhance the user experience, Zero downtime is a requirement nowadays.</p><p>Kubernetes helps in 0 downtime - Until a healthy pod starts, the new pod will not destroy itself. This way during updates you can have zero downtime, and also if some pod fails, It can be made to create replicas, etc…</p><h2 id=\"who-needs-kubernetes\">Who needs Kubernetes?</h2><p>Not every application needs Kubernetes, that said every product can have Kubernetes with its features if required. Kubernetes can help your application in many different ways but you probably can analyze different problems like resource management, downtime issues, scaling issues, and feasibility.</p><p>If you need to monitor and automate a large number of containers (micro-services), Kubernetes comes in handy. It does have different other features, which in case required for your product, you can use Kubernetes.</p><h2 id=\"conclusion\">Conclusion</h2><p>K8s is a container orchestration tool and it is used when there is an increased number of containers which can be difficult to monitor and handle. Not every application requires it, you can choose it if the features match your requirement.</p><p>A pod is a basic deployment that can be configured using YAML, the containers are deployed on pods and these pods are located on nodes, where nodes are created on clusters. It is better to know all the features of Kubernetes and match them with your application requirements, before implementing it.</p><p>For a large-scale application, Kubernetes saves a lot of time and automates almost everything related to scaling and everything with zero downtime.</p>","url":"https://backend.shahednasser.com/beginners-guide-to-kubernetes-understand-the-basics/","canonical_url":null,"uuid":"9b91ac5c-410f-4333-9364-253ca4075033","codeinjection_foot":null,"codeinjection_head":null,"codeinjection_styles":null,"comment_id":"62d068d44e918d05f353772c","reading_time":5,"send_email_when_published":null,"email_subject":null,"childHtmlRehype":{"html":"<p>You probably have heard the term Kubernetes, somewhere or the other. K8S is an abbreviated form for Kubernetes, starting with the letter ‘K’, Ending with ‘S’, and has 8 characters between the letters, hence the name.</p><p>In this blog, we will discuss what they are, how they are used, what is the workflow they have, and whether every application needs it.</p><h2 id=\"what-is-kubernetes\">What is Kubernetes?</h2><p>Kubernetes is an open-source project initially developed by Google. It is a container orchestration tool. It can be used using on-premise systems, VMs, and clouds.</p><p>Kubernetes is also provided as a service by many providers like AWS, Azure, and Google, and they are known as Amazon EKS, AKS, and GKE respectively. Each has its specific features.</p><p>I get it, if you were to ask what container orchestration is, Let’s see in short what that means,</p><h3 id=\"moving-your-application-to-the-internet\">Moving your Application to the Internet</h3><p>You have an application on your machine that you want to deploy to the internet. Let’s say that it is Irrespective of what framework you use, or it is just the html, CSS, and js, you may want to host it on a server and map it with a domain.</p><p>One of the most common ways to do that is to use a VM and copy those files over there, use Nginx or apache or anything of your preference, start a server, and map the server with a domain name.</p><h3 id=\"virtual-machines\">Virtual Machines</h3><p>VM is one of the first choices in hosting your applications for specific cases. Now, hoping your web application gets popular, how much do you think a VM can accommodate on its server? A VM is simply a computer, RAM, ROM, CPU, etc resources are fixed.</p><p>To imagine, you can think of the number of people who can use your computer simultaneously. Likewise, how will the performance be when so many users access the website at the same time? And this is dependent on the resources of the machine.</p><p>If you have higher resources, it can accommodate a lot of users and less if it has lesser resources.</p><p>These are some of the questions that arise when a website is moved to production, including how many resources you need in your case, which shows higher performance, etc... Setting up a new VM is costly since it is almost an independent machine like the one you're building these with.</p><p>Also, it is a tedious task to create, monitor, and manage multiple instances of the same and redirect them if one is busy.</p><p>These are a few problems that may arise when on a VM. Since a VM is a complete structure, it has numerous packages, OS, and many other dependencies, which are irrelevant for the application to run. Also, the resources can not be used effectively since there is no proper allocation and utilization. That is where containers arise.</p><h3 id=\"containers\">Containers</h3><p>Containers are executable software applications that contain everything it needs to run on their own. Unlike VM, containers are smaller packages and so transporting them is easier. They can also be increased in number or decreased effortlessly. This is one of the important aspects of Kubernetes.</p><p>In an application, there can be several micro-services that help the function of the app. In that case, every micro-service will be made as a container and you can see from this that, as the complexity and size of the application increases, you have to manage multiple containers. Here is where Kubernetes comes in.</p><h3 id=\"container-orchestration-tool\">Container Orchestration tool</h3><p>Kubernetes is a container orchestration tool, which means you get to increase, decrease, destroy, create, and configure containers with higher specifications and much more.</p><p>These help in scalability, monitoring, Health-checks and many more. Let’s see a real-time example of how container orchestration helps.</p><h2 id=\"short-overview-of-a-real-time-application\">Short overview of a Real-time application</h2><p>You developed a full-stack application. It will probably have a Front-end facing application, a backend, and a database.</p><p>Databases should be configured to be updated simultaneously in all the instances if we were to increase them in number, to avoid corruption of data, which again is not easier.</p><p>A database can be deployed in Kubernetes as a stateful set, but that needs a few extra configurations. There are many other different approaches other than Kubernetes for databases. Here in this blog, we will just focus on the front-end and back-end.</p><h3 id=\"containerizing-the-applications\">Containerizing the applications</h3><p>Using docker you will probably have to create a docker file and write configurations in YAML so that the front-end can serve. Nginx or apache servers are generally used for front-end containers but there are many different ways as well. Similarly, a backend container is created.</p><p>Now that you have a front-end container and a back-end container, you want to take the images of both containers and push them to an image repository.</p><h3 id=\"pushing-the-container-images\">Pushing the container images</h3><p>An image repository is generally provided by the cloud provider but Docker has its repository as well, and there are many different other image repositories available, you can choose one of your choices.</p><p>Now, you can add continuous integration and a continuous delivery pipeline in it and deliver the container images to Kubernetes or, you can send them to it directly as well. Continuous integration and continuous delivery pipeline is a different topic, you can learn about them separately and it is independent of Kubernetes.</p><p>Now that the image is pushed to Kubernetes, the image will be built and the container will run.</p><p>Now zooming out, let’s know some terms and structure of Kubernetes.</p><h2 id=\"structure-of-kubernetes-and-its-terms\">Structure of Kubernetes and its terms</h2><h3 id=\"what-are-pods-and-nodes-in-kubernetes\">What are Pods and Nodes in Kubernetes?</h3><p>A pod is a basic deployment on which your container runs. A pod can have multiple containers but generally, a pod per container is preferred.</p><p>A node can be a physical machine or virtual machine and it is where the pods are deployed. A cluster can have several nodes on them.</p><p>The order is like this: container &#x3C; pod &#x3C; node &#x3C; cluster.</p><p>We can start the pod by mentioning how many replicas we want, how many maximum replicas it can have, auto-scaling, health-check, etc.</p><p>The health-check feature checks whether a pod is healthy (running ) and if not, it will pass the information that can be made to create a new pod or inform the user about it for handling. So even if one pod fails, it will automatically detect it and can be made to create further replicas. This is mostly done with zero downtime.</p><h3 id=\"what-is-downtime\">What is downtime?</h3><p>It is the time duration, in which the server is neither accessible nor working.</p><p>Zero Downtime is something that is preferred everywhere. We all know how it is when the site we use most often is down for maintenance or because the server crashed.</p><p>To prevent this and enhance the user experience, Zero downtime is a requirement nowadays.</p><p>Kubernetes helps in 0 downtime - Until a healthy pod starts, the new pod will not destroy itself. This way during updates you can have zero downtime, and also if some pod fails, It can be made to create replicas, etc…</p><h2 id=\"who-needs-kubernetes\">Who needs Kubernetes?</h2><p>Not every application needs Kubernetes, that said every product can have Kubernetes with its features if required. Kubernetes can help your application in many different ways but you probably can analyze different problems like resource management, downtime issues, scaling issues, and feasibility.</p><p>If you need to monitor and automate a large number of containers (micro-services), Kubernetes comes in handy. It does have different other features, which in case required for your product, you can use Kubernetes.</p><h2 id=\"conclusion\">Conclusion</h2><p>K8s is a container orchestration tool and it is used when there is an increased number of containers which can be difficult to monitor and handle. Not every application requires it, you can choose it if the features match your requirement.</p><p>A pod is a basic deployment that can be configured using YAML, the containers are deployed on pods and these pods are located on nodes, where nodes are created on clusters. It is better to know all the features of Kubernetes and match them with your application requirements, before implementing it.</p><p>For a large-scale application, Kubernetes saves a lot of time and automates almost everything related to scaling and everything with zero downtime.</p>","htmlAst":{"type":"root","children":[{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"You probably have heard the term Kubernetes, somewhere or the other. K8S is an abbreviated form for Kubernetes, starting with the letter ‘K’, Ending with ‘S’, and has 8 characters between the letters, hence the name."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"In this blog, we will discuss what they are, how they are used, what is the workflow they have, and whether every application needs it."}]},{"type":"element","tagName":"h2","properties":{"id":"what-is-kubernetes"},"children":[{"type":"text","value":"What is Kubernetes?"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Kubernetes is an open-source project initially developed by Google. It is a container orchestration tool. It can be used using on-premise systems, VMs, and clouds."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Kubernetes is also provided as a service by many providers like AWS, Azure, and Google, and they are known as Amazon EKS, AKS, and GKE respectively. Each has its specific features."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"I get it, if you were to ask what container orchestration is, Let’s see in short what that means,"}]},{"type":"element","tagName":"h3","properties":{"id":"moving-your-application-to-the-internet"},"children":[{"type":"text","value":"Moving your Application to the Internet"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"You have an application on your machine that you want to deploy to the internet. Let’s say that it is Irrespective of what framework you use, or it is just the html, CSS, and js, you may want to host it on a server and map it with a domain."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"One of the most common ways to do that is to use a VM and copy those files over there, use Nginx or apache or anything of your preference, start a server, and map the server with a domain name."}]},{"type":"element","tagName":"h3","properties":{"id":"virtual-machines"},"children":[{"type":"text","value":"Virtual Machines"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"VM is one of the first choices in hosting your applications for specific cases. Now, hoping your web application gets popular, how much do you think a VM can accommodate on its server? A VM is simply a computer, RAM, ROM, CPU, etc resources are fixed."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"To imagine, you can think of the number of people who can use your computer simultaneously. Likewise, how will the performance be when so many users access the website at the same time? And this is dependent on the resources of the machine."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"If you have higher resources, it can accommodate a lot of users and less if it has lesser resources."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"These are some of the questions that arise when a website is moved to production, including how many resources you need in your case, which shows higher performance, etc... Setting up a new VM is costly since it is almost an independent machine like the one you're building these with."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Also, it is a tedious task to create, monitor, and manage multiple instances of the same and redirect them if one is busy."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"These are a few problems that may arise when on a VM. Since a VM is a complete structure, it has numerous packages, OS, and many other dependencies, which are irrelevant for the application to run. Also, the resources can not be used effectively since there is no proper allocation and utilization. That is where containers arise."}]},{"type":"element","tagName":"h3","properties":{"id":"containers"},"children":[{"type":"text","value":"Containers"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Containers are executable software applications that contain everything it needs to run on their own. Unlike VM, containers are smaller packages and so transporting them is easier. They can also be increased in number or decreased effortlessly. This is one of the important aspects of Kubernetes."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"In an application, there can be several micro-services that help the function of the app. In that case, every micro-service will be made as a container and you can see from this that, as the complexity and size of the application increases, you have to manage multiple containers. Here is where Kubernetes comes in."}]},{"type":"element","tagName":"h3","properties":{"id":"container-orchestration-tool"},"children":[{"type":"text","value":"Container Orchestration tool"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Kubernetes is a container orchestration tool, which means you get to increase, decrease, destroy, create, and configure containers with higher specifications and much more."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"These help in scalability, monitoring, Health-checks and many more. Let’s see a real-time example of how container orchestration helps."}]},{"type":"element","tagName":"h2","properties":{"id":"short-overview-of-a-real-time-application"},"children":[{"type":"text","value":"Short overview of a Real-time application"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"You developed a full-stack application. It will probably have a Front-end facing application, a backend, and a database."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Databases should be configured to be updated simultaneously in all the instances if we were to increase them in number, to avoid corruption of data, which again is not easier."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"A database can be deployed in Kubernetes as a stateful set, but that needs a few extra configurations. There are many other different approaches other than Kubernetes for databases. Here in this blog, we will just focus on the front-end and back-end."}]},{"type":"element","tagName":"h3","properties":{"id":"containerizing-the-applications"},"children":[{"type":"text","value":"Containerizing the applications"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Using docker you will probably have to create a docker file and write configurations in YAML so that the front-end can serve. Nginx or apache servers are generally used for front-end containers but there are many different ways as well. Similarly, a backend container is created."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Now that you have a front-end container and a back-end container, you want to take the images of both containers and push them to an image repository."}]},{"type":"element","tagName":"h3","properties":{"id":"pushing-the-container-images"},"children":[{"type":"text","value":"Pushing the container images"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"An image repository is generally provided by the cloud provider but Docker has its repository as well, and there are many different other image repositories available, you can choose one of your choices."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Now, you can add continuous integration and a continuous delivery pipeline in it and deliver the container images to Kubernetes or, you can send them to it directly as well. Continuous integration and continuous delivery pipeline is a different topic, you can learn about them separately and it is independent of Kubernetes."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Now that the image is pushed to Kubernetes, the image will be built and the container will run."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Now zooming out, let’s know some terms and structure of Kubernetes."}]},{"type":"element","tagName":"h2","properties":{"id":"structure-of-kubernetes-and-its-terms"},"children":[{"type":"text","value":"Structure of Kubernetes and its terms"}]},{"type":"element","tagName":"h3","properties":{"id":"what-are-pods-and-nodes-in-kubernetes"},"children":[{"type":"text","value":"What are Pods and Nodes in Kubernetes?"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"A pod is a basic deployment on which your container runs. A pod can have multiple containers but generally, a pod per container is preferred."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"A node can be a physical machine or virtual machine and it is where the pods are deployed. A cluster can have several nodes on them."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"The order is like this: container < pod < node < cluster."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"We can start the pod by mentioning how many replicas we want, how many maximum replicas it can have, auto-scaling, health-check, etc."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"The health-check feature checks whether a pod is healthy (running ) and if not, it will pass the information that can be made to create a new pod or inform the user about it for handling. So even if one pod fails, it will automatically detect it and can be made to create further replicas. This is mostly done with zero downtime."}]},{"type":"element","tagName":"h3","properties":{"id":"what-is-downtime"},"children":[{"type":"text","value":"What is downtime?"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"It is the time duration, in which the server is neither accessible nor working."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Zero Downtime is something that is preferred everywhere. We all know how it is when the site we use most often is down for maintenance or because the server crashed."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"To prevent this and enhance the user experience, Zero downtime is a requirement nowadays."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Kubernetes helps in 0 downtime - Until a healthy pod starts, the new pod will not destroy itself. This way during updates you can have zero downtime, and also if some pod fails, It can be made to create replicas, etc…"}]},{"type":"element","tagName":"h2","properties":{"id":"who-needs-kubernetes"},"children":[{"type":"text","value":"Who needs Kubernetes?"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Not every application needs Kubernetes, that said every product can have Kubernetes with its features if required. Kubernetes can help your application in many different ways but you probably can analyze different problems like resource management, downtime issues, scaling issues, and feasibility."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"If you need to monitor and automate a large number of containers (micro-services), Kubernetes comes in handy. It does have different other features, which in case required for your product, you can use Kubernetes."}]},{"type":"element","tagName":"h2","properties":{"id":"conclusion"},"children":[{"type":"text","value":"Conclusion"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"K8s is a container orchestration tool and it is used when there is an increased number of containers which can be difficult to monitor and handle. Not every application requires it, you can choose it if the features match your requirement."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"A pod is a basic deployment that can be configured using YAML, the containers are deployed on pods and these pods are located on nodes, where nodes are created on clusters. It is better to know all the features of Kubernetes and match them with your application requirements, before implementing it."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"For a large-scale application, Kubernetes saves a lot of time and automates almost everything related to scaling and everything with zero downtime."}]}],"data":{"quirksMode":false}},"tableOfContents":[{"id":"what-is-kubernetes","heading":"What is Kubernetes?","items":[{"id":"moving-your-application-to-the-internet","heading":"Moving your Application to the Internet"},{"id":"virtual-machines","heading":"Virtual Machines"},{"id":"containers","heading":"Containers"},{"id":"container-orchestration-tool","heading":"Container Orchestration tool"}]},{"id":"short-overview-of-a-real-time-application","heading":"Short overview of a Real-time application","items":[{"id":"containerizing-the-applications","heading":"Containerizing the applications"},{"id":"pushing-the-container-images","heading":"Pushing the container images"}]},{"id":"structure-of-kubernetes-and-its-terms","heading":"Structure of Kubernetes and its terms","items":[{"id":"what-are-pods-and-nodes-in-kubernetes","heading":"What are Pods and Nodes in Kubernetes?"},{"id":"what-is-downtime","heading":"What is downtime?"}]},{"id":"who-needs-kubernetes","heading":"Who needs Kubernetes?"},{"id":"conclusion","heading":"Conclusion"}]},"featureImageSharp":{"base":"Beginner-s-Guide-to-Kubernetes--Understand-the-Basics.jpg","publicURL":"/static/23269b2f0186ef1e0efa7f55bf52c4ab/Beginner-s-Guide-to-Kubernetes--Understand-the-Basics.jpg","imageMeta":{"width":1560,"height":876},"childImageSharp":{"fluid":{"base64":"data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAALABQDASIAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAAAAEDBf/EABQBAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhADEAAAAe20EUf/xAAXEAADAQAAAAAAAAAAAAAAAAAAARIg/9oACAEBAAEFAqKef//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQMBAT8BP//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQIBAT8BP//EABcQAAMBAAAAAAAAAAAAAAAAAAABMiD/2gAIAQEABj8ClkvP/8QAGBABAAMBAAAAAAAAAAAAAAAAAQARISD/2gAIAQEAAT8hVaQEgaaVx//aAAwDAQACAAMAAAAQw8//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/ED//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/ED//xAAbEAEBAAEFAAAAAAAAAAAAAAARAQAgIUFRcf/aAAgBAQABPxCNgUZzlAD3bLqI6XR//9k=","aspectRatio":1.7857142857142858,"src":"/static/23269b2f0186ef1e0efa7f55bf52c4ab/ea4ab/Beginner-s-Guide-to-Kubernetes--Understand-the-Basics.jpg","srcSet":"/static/23269b2f0186ef1e0efa7f55bf52c4ab/477ba/Beginner-s-Guide-to-Kubernetes--Understand-the-Basics.jpg 175w,\n/static/23269b2f0186ef1e0efa7f55bf52c4ab/06776/Beginner-s-Guide-to-Kubernetes--Understand-the-Basics.jpg 350w,\n/static/23269b2f0186ef1e0efa7f55bf52c4ab/ea4ab/Beginner-s-Guide-to-Kubernetes--Understand-the-Basics.jpg 700w,\n/static/23269b2f0186ef1e0efa7f55bf52c4ab/3055e/Beginner-s-Guide-to-Kubernetes--Understand-the-Basics.jpg 1050w,\n/static/23269b2f0186ef1e0efa7f55bf52c4ab/eff08/Beginner-s-Guide-to-Kubernetes--Understand-the-Basics.jpg 1400w,\n/static/23269b2f0186ef1e0efa7f55bf52c4ab/81a53/Beginner-s-Guide-to-Kubernetes--Understand-the-Basics.jpg 1560w","srcWebp":"/static/23269b2f0186ef1e0efa7f55bf52c4ab/89afa/Beginner-s-Guide-to-Kubernetes--Understand-the-Basics.webp","srcSetWebp":"/static/23269b2f0186ef1e0efa7f55bf52c4ab/9fca7/Beginner-s-Guide-to-Kubernetes--Understand-the-Basics.webp 175w,\n/static/23269b2f0186ef1e0efa7f55bf52c4ab/37a4e/Beginner-s-Guide-to-Kubernetes--Understand-the-Basics.webp 350w,\n/static/23269b2f0186ef1e0efa7f55bf52c4ab/89afa/Beginner-s-Guide-to-Kubernetes--Understand-the-Basics.webp 700w,\n/static/23269b2f0186ef1e0efa7f55bf52c4ab/78e7a/Beginner-s-Guide-to-Kubernetes--Understand-the-Basics.webp 1050w,\n/static/23269b2f0186ef1e0efa7f55bf52c4ab/03d34/Beginner-s-Guide-to-Kubernetes--Understand-the-Basics.webp 1400w,\n/static/23269b2f0186ef1e0efa7f55bf52c4ab/f5845/Beginner-s-Guide-to-Kubernetes--Understand-the-Basics.webp 1560w","sizes":"(max-width: 700px) 100vw, 700px"}}}},"allGhostPost":{"edges":[{"node":{"id":"Ghost__Post__6263f18539840e1ac287510b","title":"How to use Transitions in React 18","slug":"how-to-use-transitions-in-react-18","featured":true,"feature_image":"https://backend.shahednasser.com/content/images/2022/04/How-to-use-Transitions-in-React-18-2.jpg","excerpt":"In this tutorial, you'll learn more about Transitions in React 18 and see them in action.","custom_excerpt":"In this tutorial, you'll learn more about Transitions in React 18 and see them in action.","visibility":"public","created_at_pretty":"23 Apr 2022","published_at_pretty":"25 Apr 2022","updated_at_pretty":"25 Apr 2022","created_at":"2022-04-23T12:31:01.000+00:00","published_at":"2022-04-25T09:13:48.000+00:00","updated_at":"2022-04-25T09:13:48.000+00:00","meta_title":null,"meta_description":null,"og_description":null,"og_image":null,"og_title":null,"twitter_description":null,"twitter_image":null,"twitter_title":null,"authors":[{"slug":"shahed","url":"https://backend.shahednasser.com/author/shahed/","name":"Shahed Nasser","bio":null,"cover_image":null,"profile_image":"https://backend.shahednasser.com/content/images/2022/03/IMG_0591.jpg","location":null,"website":null,"twitter":null,"facebook":null,"meta_title":null,"meta_description":null,"coverImageSharp":null,"profileImageSharp":null}],"primary_author":{"slug":"shahed","url":"https://backend.shahednasser.com/author/shahed/","name":"Shahed Nasser","bio":null,"cover_image":null,"profile_image":"https://backend.shahednasser.com/content/images/2022/03/IMG_0591.jpg","location":null,"website":null,"twitter":null,"facebook":null,"meta_title":null,"meta_description":null,"coverImageSharp":null,"profileImageSharp":{"base":"IMG_0591.jpg","publicURL":"/static/ceb49c3c631485453e71e00d7f84b069/IMG_0591.jpg","imageMeta":{"width":1182,"height":1179},"childImageSharp":{"fluid":{"base64":"data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAUABQDASIAAhEBAxEB/8QAGAABAQEBAQAAAAAAAAAAAAAAAAMEAQL/xAAWAQEBAQAAAAAAAAAAAAAAAAADBAL/2gAMAwEAAhADEAAAAdXiFM6i0CohUWXoKn//xAAcEAACAgIDAAAAAAAAAAAAAAACAwESBBEhM0H/2gAIAQEAAQUCWySE3WEr7SzbXjAj4iKty+sOQ//EABYRAQEBAAAAAAAAAAAAAAAAAAERIP/aAAgBAwEBPwEhj//EABQRAQAAAAAAAAAAAAAAAAAAACD/2gAIAQIBAT8BH//EAB4QAAIBBAMBAAAAAAAAAAAAAAABIRESMUECECJx/9oACAEBAAY/ApVGWvOjzgtUwLlTZA0sdL4f/8QAHBAAAwACAwEAAAAAAAAAAAAAAAERITFBkbHB/9oACAEBAAE/IahkCy+N2GwZpjQiJHJCspUFY0QrSi+HqiW2rgf/2gAMAwEAAgADAAAAEPw3/wD/xAAYEQEBAAMAAAAAAAAAAAAAAAAAARExQf/aAAgBAwEBPxCtjDqP/8QAFxEBAQEBAAAAAAAAAAAAAAAAAQAxEf/aAAgBAgEBPxBFus6Tt//EAB8QAQEAAgIBBQAAAAAAAAAAAAERACExQWFRcYGR0f/aAAgBAQABPxAuaBPPzkO1wyX7F4wkwXanfZrFQgeqE9JgS14vVOvrERIJomVBKwt2jebAeP0yVa8h1n//2Q==","aspectRatio":1,"src":"/static/ceb49c3c631485453e71e00d7f84b069/31709/IMG_0591.jpg","srcSet":"/static/ceb49c3c631485453e71e00d7f84b069/f340b/IMG_0591.jpg 28w,\n/static/ceb49c3c631485453e71e00d7f84b069/22d64/IMG_0591.jpg 55w,\n/static/ceb49c3c631485453e71e00d7f84b069/31709/IMG_0591.jpg 110w,\n/static/ceb49c3c631485453e71e00d7f84b069/aa249/IMG_0591.jpg 165w,\n/static/ceb49c3c631485453e71e00d7f84b069/0dc33/IMG_0591.jpg 220w,\n/static/ceb49c3c631485453e71e00d7f84b069/d8257/IMG_0591.jpg 1182w","srcWebp":"/static/ceb49c3c631485453e71e00d7f84b069/8678c/IMG_0591.webp","srcSetWebp":"/static/ceb49c3c631485453e71e00d7f84b069/59cda/IMG_0591.webp 28w,\n/static/ceb49c3c631485453e71e00d7f84b069/7da75/IMG_0591.webp 55w,\n/static/ceb49c3c631485453e71e00d7f84b069/8678c/IMG_0591.webp 110w,\n/static/ceb49c3c631485453e71e00d7f84b069/f282e/IMG_0591.webp 165w,\n/static/ceb49c3c631485453e71e00d7f84b069/a7b21/IMG_0591.webp 220w,\n/static/ceb49c3c631485453e71e00d7f84b069/63099/IMG_0591.webp 1182w","sizes":"(max-width: 110px) 100vw, 110px"}}}},"primary_tag":{"slug":"react","url":"https://backend.shahednasser.com/tag/react/","name":"React","visibility":"public","feature_image":"https://images.unsplash.com/photo-1581276879432-15e50529f34b?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=MnwxMTc3M3wwfDF8c2VhcmNofDN8fHJlYWN0fGVufDB8fHx8MTYyMjYzMzI0MA&ixlib=rb-1.2.1&q=80&w=2000","description":"Learn more about React through tutorials, articles, and tips.","meta_title":null,"meta_description":null,"featureImageSharp":{"base":"photo-1581276879432-15e50529f34b.jpg","publicURL":"/static/7140ea32e1157ba61402d5d67ab846d4/photo-1581276879432-15e50529f34b.jpg","imageMeta":{"width":2000,"height":1333},"childImageSharp":{"fluid":{"base64":"data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAANABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAIDBf/EABUBAQEAAAAAAAAAAAAAAAAAAAAB/9oADAMBAAIQAxAAAAHJai1MBP/EABcQAAMBAAAAAAAAAAAAAAAAAAABEBH/2gAIAQEAAQUCuDU//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPwE//8QAFREBAQAAAAAAAAAAAAAAAAAAEBH/2gAIAQIBAT8Bh//EABQQAQAAAAAAAAAAAAAAAAAAACD/2gAIAQEABj8CX//EABgQAQEBAQEAAAAAAAAAAAAAAAABESFR/9oACAEBAAE/IYy+rHKDH//aAAwDAQACAAMAAAAQC9//xAAVEQEBAAAAAAAAAAAAAAAAAAAQEf/aAAgBAwEBPxCn/8QAFREBAQAAAAAAAAAAAAAAAAAAARD/2gAIAQIBAT8QUT//xAAaEAADAQADAAAAAAAAAAAAAAAAAREhQWFx/9oACAEBAAE/EMY0neijzwMrrVEm7auUQPNGlP/Z","aspectRatio":1.5028901734104045,"src":"/static/7140ea32e1157ba61402d5d67ab846d4/d5c54/photo-1581276879432-15e50529f34b.jpg","srcSet":"/static/7140ea32e1157ba61402d5d67ab846d4/65d8c/photo-1581276879432-15e50529f34b.jpg 260w,\n/static/7140ea32e1157ba61402d5d67ab846d4/c5f21/photo-1581276879432-15e50529f34b.jpg 520w,\n/static/7140ea32e1157ba61402d5d67ab846d4/d5c54/photo-1581276879432-15e50529f34b.jpg 1040w,\n/static/7140ea32e1157ba61402d5d67ab846d4/81a53/photo-1581276879432-15e50529f34b.jpg 1560w,\n/static/7140ea32e1157ba61402d5d67ab846d4/4e5f3/photo-1581276879432-15e50529f34b.jpg 2000w","srcWebp":"/static/7140ea32e1157ba61402d5d67ab846d4/e4875/photo-1581276879432-15e50529f34b.webp","srcSetWebp":"/static/7140ea32e1157ba61402d5d67ab846d4/dc8f3/photo-1581276879432-15e50529f34b.webp 260w,\n/static/7140ea32e1157ba61402d5d67ab846d4/2db4b/photo-1581276879432-15e50529f34b.webp 520w,\n/static/7140ea32e1157ba61402d5d67ab846d4/e4875/photo-1581276879432-15e50529f34b.webp 1040w,\n/static/7140ea32e1157ba61402d5d67ab846d4/f5845/photo-1581276879432-15e50529f34b.webp 1560w,\n/static/7140ea32e1157ba61402d5d67ab846d4/49d6b/photo-1581276879432-15e50529f34b.webp 2000w","sizes":"(max-width: 1040px) 100vw, 1040px"}}}},"tags":[{"slug":"react","url":"https://backend.shahednasser.com/tag/react/","name":"React","visibility":"public","feature_image":"https://images.unsplash.com/photo-1581276879432-15e50529f34b?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=MnwxMTc3M3wwfDF8c2VhcmNofDN8fHJlYWN0fGVufDB8fHx8MTYyMjYzMzI0MA&ixlib=rb-1.2.1&q=80&w=2000","description":"Learn more about React through tutorials, articles, and tips.","meta_title":null,"meta_description":null,"featureImageSharp":null}],"plaintext":"React 18 came out at the end of March with a bundle of new features. One of these new features is Transitions.\n\nIn this tutorial, you'll learn more about Transitions in React 18 and see them in action.\n\n\nDefinition\n\nYou have 2 types of transitions. Urgent transitions and non-urgent transitions.\n\n\nUrgent Transitions\n\nUrgent transitions are transitions that the user needs to see instantly. For example, if the user changes their profile name and saves it, they should be able to see the change in the displayed profile name in the navigation bar.\n\nUrgent transitions are done the same way you've been setting a state before:\n\nconst [name, setName] = useState('');\n\nfunction handleChange (e) {\n\tsetName(e.target.value); //urgent transition\n}\n\n\nNon-Urgent Transitions\n\nNon-urgent transitions are transitions that are ok to be delayed a little. For example, if the user is performing a search, it's ok for the results to appear not so instantly.\n\nThere are 2 ways to start a non-urgent transition. The first one is using the hook useTransition:\n\nimport {useTransition, useState} from 'react';\n\nexport default function MyApp() {\n    const [results, setResults] = useState([]);\n    const [pending, startTransition] = useTransition();\n    \n    function handleChange(e) {\n        let tempResults = [];\n        ... // set results from APIs\n        startTransition(() => {\n            setResults(tempResults);\n        });\n    }\n}\n\nThe hook returns the boolean variable pending which indicates whether the transition is active or not. It can be used to show a loading component.\n\nThe hook also returns a function startTransition that accepts a callback function in which you set the state. The state will not be set immediately.\n\nThe second way to start a non-urgent transition is using the function startTransition imported directly from React:\n\nimport {startTransition} from 'react';\n\nexport default function MyApp() {\n    const [results, setResults] = useState([]);\n    \n    function handleChange(e) {\n        let tempResults = [];\n        ... // set results from APIs\n        startTransition(() => {\n            setResults(tempResults);\n        });\n    }\n}\n\nThis approach does not give you access to a variable like isPending to check whether the transition is active or not.\n\nThis approach is mainly available for places in your code when you can't use hooks like useTransition.\n\n\nUsage Example\n\nIn this example, you'll be creating a number input that accepts a large number of images to be shown. Then, random images will be retrieved using Falso.\n\nStart by creating a new React app if you don't have one available:\n\nnpx create-react-app my-app\n\nNext, change into the directory my-app:\n\ncd my-app\n\nThen, install the Falso library:\n\nnpm i @ngneat/falso\n\nNow, open src/App.js and change it to the following:\n\nimport './App.css';\n\nimport { useState, useTransition } from 'react';\n\nimport { randImg } from '@ngneat/falso';\n\nfunction App() {\n  const [number, setNumber] = useState(5000);\n  const [images, setImages] = useState([])\n  const [isPending, startTransition] = useTransition();\n\n  function showImages() {\n    //TODO add transition\n  }\n\n  return (\n    <div style={{\n      padding: '10px'\n    }}>\n      <h1>Images</h1>\n      <div>\n        <label>Number of images</label>\n        <input type=\"number\" min=\"1\" max=\"10000\" value={number} onChange={(e) => setNumber(e.target.value)} style={{\n          display: 'block',\n          marginTop: '10px',\n          width: '3rem'\n        }} />\n        <button type=\"button\" onClick={showImages} style={{marginTop: '10px'}}>Show Images</button>\n      </div>\n      <div>\n        <span>Number selected: {number}</span><br/>\n        <span>Results:</span>\n        {isPending && <span>Loading...</span>}\n        {!isPending && images.length > 0 && images}\n      </div>\n    </div>\n  );\n}\n\nexport default App;\n\n\nYou first create 2 state variables number and images. You also use useTransition which gives you access to isPending and startTransition.\n\nIn the returned JSX, you show a number input and a button that will later retrieve the images on click.\n\nBelow the input and button, the number entered by the user in the input will be shown. Notice that in the onChange event handler for the input the name is updated urgently. This will show the number instantly as it is updated by the user.\n\nLet's test it out now. Run the website server:\n\nnpm start\n\nThis will open the website in your browser. If you try to update the input, you'll notice that the number displayed below it will update instantly.\n\n0:00/1×\n\nNow, let's test the non-urgent transition. In showImages replace the TODO with the following code:\n\nconst imgSources = randImg({length: number}).map((url, index) => <img src={`${url}?v=${index}`} key={index} />);\nstartTransition(() => {\n\tsetImages(imgSources);\n})\n\nThis will get the images using the falso library and inside startTransition with set the images state variable.\n\nNotice that in the returned JSX of the function we use isPending to indicate whether to show \"Loading...\" or not.\n\nIf you try clicking on the button now, the \"Loading...\" text will show first, and then the images will be shown gradually.\n\n0:00/1×\n\n\nConclusion\n\nTransitions in React 18 allow you to optimize your user experience, especially for tasks or features that require some time to load. You can now use Transitions in React 18 to differentiate between instate updates and updates that can be delayed, and show in the UI any necessary loading more efficiently for those that require more time.","html":"<p><a href=\"https://reactjs.org/blog/2022/03/29/react-v18.html\">React 18 came out at the end of March</a> with a bundle of new features. One of these new features is Transitions.</p><p>In this tutorial, you'll learn more about Transitions in React 18 and see them in action.</p><h2 id=\"definition\">Definition</h2><p>You have 2 types of transitions. Urgent transitions and non-urgent transitions.</p><h3 id=\"urgent-transitions\">Urgent Transitions</h3><p>Urgent transitions are transitions that the user needs to see instantly. For example, if the user changes their profile name and saves it, they should be able to see the change in the displayed profile name in the navigation bar.</p><p>Urgent transitions are done the same way you've been setting a state before:</p><pre><code class=\"language-js\">const [name, setName] = useState('');\n\nfunction handleChange (e) {\n\tsetName(e.target.value); //urgent transition\n}</code></pre><h3 id=\"non-urgent-transitions\">Non-Urgent Transitions</h3><p>Non-urgent transitions are transitions that are ok to be delayed a little. For example, if the user is performing a search, it's ok for the results to appear not so instantly.</p><p>There are 2 ways to start a non-urgent transition. The first one is using the hook <code>useTransition</code>: </p><pre><code class=\"language-js\">import {useTransition, useState} from 'react';\n\nexport default function MyApp() {\n    const [results, setResults] = useState([]);\n    const [pending, startTransition] = useTransition();\n    \n    function handleChange(e) {\n        let tempResults = [];\n        ... // set results from APIs\n        startTransition(() =&gt; {\n            setResults(tempResults);\n        });\n    }\n}</code></pre><p>The hook returns the boolean variable <code>pending</code> which indicates whether the transition is active or not. It can be used to show a loading component.</p><p>The hook also returns a function <code>startTransition</code> that accepts a callback function in which you set the state. The state will not be set immediately.</p><p>The second way to start a non-urgent transition is using the function <code>startTransition</code> imported directly from React:</p><pre><code class=\"language-js\">import {startTransition} from 'react';\n\nexport default function MyApp() {\n    const [results, setResults] = useState([]);\n    \n    function handleChange(e) {\n        let tempResults = [];\n        ... // set results from APIs\n        startTransition(() =&gt; {\n            setResults(tempResults);\n        });\n    }\n}</code></pre><p>This approach does not give you access to a variable like <code>isPending</code> to check whether the transition is active or not.</p><p>This approach is mainly available for places in your code when you can't use hooks like <code>useTransition</code>.</p><h2 id=\"usage-example\">Usage Example</h2><p>In this example, you'll be creating a number input that accepts a large number of images to be shown. Then, random images will be retrieved using <a href=\"https://ngneat.github.io/falso/\">Falso</a>.</p><p>Start by creating a new React app if you don't have one available:</p><pre><code class=\"language-bash\">npx create-react-app my-app</code></pre><p>Next, change into the directory <code>my-app</code>:</p><pre><code class=\"language-bash\">cd my-app</code></pre><p>Then, install the Falso library:</p><pre><code class=\"language-bash\">npm i @ngneat/falso</code></pre><p>Now, open <code>src/App.js</code> and change it to the following:</p><pre><code class=\"language-js\">import './App.css';\n\nimport { useState, useTransition } from 'react';\n\nimport { randImg } from '@ngneat/falso';\n\nfunction App() {\n  const [number, setNumber] = useState(5000);\n  const [images, setImages] = useState([])\n  const [isPending, startTransition] = useTransition();\n\n  function showImages() {\n    //TODO add transition\n  }\n\n  return (\n    &lt;div style={{\n      padding: '10px'\n    }}&gt;\n      &lt;h1&gt;Images&lt;/h1&gt;\n      &lt;div&gt;\n        &lt;label&gt;Number of images&lt;/label&gt;\n        &lt;input type=\"number\" min=\"1\" max=\"10000\" value={number} onChange={(e) =&gt; setNumber(e.target.value)} style={{\n          display: 'block',\n          marginTop: '10px',\n          width: '3rem'\n        }} /&gt;\n        &lt;button type=\"button\" onClick={showImages} style={{marginTop: '10px'}}&gt;Show Images&lt;/button&gt;\n      &lt;/div&gt;\n      &lt;div&gt;\n        &lt;span&gt;Number selected: {number}&lt;/span&gt;&lt;br/&gt;\n        &lt;span&gt;Results:&lt;/span&gt;\n        {isPending &amp;&amp; &lt;span&gt;Loading...&lt;/span&gt;}\n        {!isPending &amp;&amp; images.length &gt; 0 &amp;&amp; images}\n      &lt;/div&gt;\n    &lt;/div&gt;\n  );\n}\n\nexport default App;\n</code></pre><p>You first create 2 state variables <code>number</code> and <code>images</code>. You also use <code>useTransition</code> which gives you access to <code>isPending</code> and <code>startTransition</code>.</p><p>In the returned JSX, you show a number input and a button that will later retrieve the images on click.</p><p>Below the input and button, the number entered by the user in the input will be shown. Notice that in the <code>onChange</code> event handler for the input the name is updated <strong>urgently. </strong>This will show the number instantly as it is updated by the user.</p><p>Let's test it out now. Run the website server:</p><pre><code class=\"language-bash\">npm start</code></pre><p>This will open the website in your browser. If you try to update the input, you'll notice that the number displayed below it will update instantly.</p><figure class=\"kg-card kg-video-card\"><div class=\"kg-video-container\"><video src=\"https://backend.shahednasser.com/content/media/2022/04/Screen-Recording-2022-04-23-at-3.45.38-PM.mp4\" poster=\"https://img.spacergif.org/v1/798x692/0a/spacer.png\" width=\"798\" height=\"692\" playsinline preload=\"metadata\" style=\"background: transparent url('https://backend.shahednasser.com/content/images/2022/04/media-thumbnail-ember409.jpg') 50% 50% / cover no-repeat;\" /></video><div class=\"kg-video-overlay\"><button class=\"kg-video-large-play-icon\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M23.14 10.608 2.253.164A1.559 1.559 0 0 0 0 1.557v20.887a1.558 1.558 0 0 0 2.253 1.392L23.14 13.393a1.557 1.557 0 0 0 0-2.785Z\"/></svg></button></div><div class=\"kg-video-player-container\"><div class=\"kg-video-player\"><button class=\"kg-video-play-icon\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M23.14 10.608 2.253.164A1.559 1.559 0 0 0 0 1.557v20.887a1.558 1.558 0 0 0 2.253 1.392L23.14 13.393a1.557 1.557 0 0 0 0-2.785Z\"/></svg></button><button class=\"kg-video-pause-icon kg-video-hide\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><rect x=\"3\" y=\"1\" width=\"7\" height=\"22\" rx=\"1.5\" ry=\"1.5\"/><rect x=\"14\" y=\"1\" width=\"7\" height=\"22\" rx=\"1.5\" ry=\"1.5\"/></svg></button><span class=\"kg-video-current-time\">0:00</span><div class=\"kg-video-time\">/<span class=\"kg-video-duration\"></span></div><input type=\"range\" class=\"kg-video-seek-slider\" max=\"100\" value=\"0\"><button class=\"kg-video-playback-rate\">1&#215;</button><button class=\"kg-video-unmute-icon\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M15.189 2.021a9.728 9.728 0 0 0-7.924 4.85.249.249 0 0 1-.221.133H5.25a3 3 0 0 0-3 3v2a3 3 0 0 0 3 3h1.794a.249.249 0 0 1 .221.133 9.73 9.73 0 0 0 7.924 4.85h.06a1 1 0 0 0 1-1V3.02a1 1 0 0 0-1.06-.998Z\"/></svg></button><button class=\"kg-video-mute-icon kg-video-hide\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M16.177 4.3a.248.248 0 0 0 .073-.176v-1.1a1 1 0 0 0-1.061-1 9.728 9.728 0 0 0-7.924 4.85.249.249 0 0 1-.221.133H5.25a3 3 0 0 0-3 3v2a3 3 0 0 0 3 3h.114a.251.251 0 0 0 .177-.073ZM23.707 1.706A1 1 0 0 0 22.293.292l-22 22a1 1 0 0 0 0 1.414l.009.009a1 1 0 0 0 1.405-.009l6.63-6.631A.251.251 0 0 1 8.515 17a.245.245 0 0 1 .177.075 10.081 10.081 0 0 0 6.5 2.92 1 1 0 0 0 1.061-1V9.266a.247.247 0 0 1 .073-.176Z\"/></svg></button><input type=\"range\" class=\"kg-video-volume-slider\" max=\"100\" value=\"100\"></div></div></div></figure><p>Now, let's test the non-urgent transition. In <code>showImages</code> replace the <code>TODO</code> with the following code:</p><pre><code class=\"language-js\">const imgSources = randImg({length: number}).map((url, index) =&gt; &lt;img src={`${url}?v=${index}`} key={index} /&gt;);\nstartTransition(() =&gt; {\n\tsetImages(imgSources);\n})</code></pre><p>This will get the images using the <code>falso</code> library and inside <code>startTransition</code> with set the <code>images</code> state variable.</p><p>Notice that in the returned JSX of the function we use <code>isPending</code> to indicate whether to show \"Loading...\" or not.</p><p>If you try clicking on the button now, the \"Loading...\" text will show first, and then the images will be shown gradually.</p><figure class=\"kg-card kg-video-card\"><div class=\"kg-video-container\"><video src=\"https://backend.shahednasser.com/content/media/2022/04/Screen-Recording-2022-04-23-at-4.01.34-PM.mp4\" poster=\"https://img.spacergif.org/v1/794x896/0a/spacer.png\" width=\"794\" height=\"896\" playsinline preload=\"metadata\" style=\"background: transparent url('https://backend.shahednasser.com/content/images/2022/04/media-thumbnail-ember441.jpg') 50% 50% / cover no-repeat;\" /></video><div class=\"kg-video-overlay\"><button class=\"kg-video-large-play-icon\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M23.14 10.608 2.253.164A1.559 1.559 0 0 0 0 1.557v20.887a1.558 1.558 0 0 0 2.253 1.392L23.14 13.393a1.557 1.557 0 0 0 0-2.785Z\"/></svg></button></div><div class=\"kg-video-player-container\"><div class=\"kg-video-player\"><button class=\"kg-video-play-icon\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M23.14 10.608 2.253.164A1.559 1.559 0 0 0 0 1.557v20.887a1.558 1.558 0 0 0 2.253 1.392L23.14 13.393a1.557 1.557 0 0 0 0-2.785Z\"/></svg></button><button class=\"kg-video-pause-icon kg-video-hide\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><rect x=\"3\" y=\"1\" width=\"7\" height=\"22\" rx=\"1.5\" ry=\"1.5\"/><rect x=\"14\" y=\"1\" width=\"7\" height=\"22\" rx=\"1.5\" ry=\"1.5\"/></svg></button><span class=\"kg-video-current-time\">0:00</span><div class=\"kg-video-time\">/<span class=\"kg-video-duration\"></span></div><input type=\"range\" class=\"kg-video-seek-slider\" max=\"100\" value=\"0\"><button class=\"kg-video-playback-rate\">1&#215;</button><button class=\"kg-video-unmute-icon\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M15.189 2.021a9.728 9.728 0 0 0-7.924 4.85.249.249 0 0 1-.221.133H5.25a3 3 0 0 0-3 3v2a3 3 0 0 0 3 3h1.794a.249.249 0 0 1 .221.133 9.73 9.73 0 0 0 7.924 4.85h.06a1 1 0 0 0 1-1V3.02a1 1 0 0 0-1.06-.998Z\"/></svg></button><button class=\"kg-video-mute-icon kg-video-hide\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M16.177 4.3a.248.248 0 0 0 .073-.176v-1.1a1 1 0 0 0-1.061-1 9.728 9.728 0 0 0-7.924 4.85.249.249 0 0 1-.221.133H5.25a3 3 0 0 0-3 3v2a3 3 0 0 0 3 3h.114a.251.251 0 0 0 .177-.073ZM23.707 1.706A1 1 0 0 0 22.293.292l-22 22a1 1 0 0 0 0 1.414l.009.009a1 1 0 0 0 1.405-.009l6.63-6.631A.251.251 0 0 1 8.515 17a.245.245 0 0 1 .177.075 10.081 10.081 0 0 0 6.5 2.92 1 1 0 0 0 1.061-1V9.266a.247.247 0 0 1 .073-.176Z\"/></svg></button><input type=\"range\" class=\"kg-video-volume-slider\" max=\"100\" value=\"100\"></div></div></div></figure><h2 id=\"conclusion\">Conclusion</h2><p>Transitions in React 18 allow you to optimize your user experience, especially for tasks or features that require some time to load. You can now use Transitions in React 18 to differentiate between instate updates and updates that can be delayed, and show in the UI any necessary loading more efficiently for those that require more time.</p>","url":"https://backend.shahednasser.com/how-to-use-transitions-in-react-18/","canonical_url":null,"uuid":"b77353b0-096c-4619-b2b2-bab7e980f5c4","codeinjection_foot":null,"codeinjection_head":null,"codeinjection_styles":null,"comment_id":"6263f18539840e1ac287510b","reading_time":3,"send_email_when_published":null,"email_subject":null,"childHtmlRehype":{"html":"<p><a href=\"https://reactjs.org/blog/2022/03/29/react-v18.html\">React 18 came out at the end of March</a> with a bundle of new features. One of these new features is Transitions.</p><p>In this tutorial, you'll learn more about Transitions in React 18 and see them in action.</p><h2 id=\"definition\">Definition</h2><p>You have 2 types of transitions. Urgent transitions and non-urgent transitions.</p><h3 id=\"urgent-transitions\">Urgent Transitions</h3><p>Urgent transitions are transitions that the user needs to see instantly. For example, if the user changes their profile name and saves it, they should be able to see the change in the displayed profile name in the navigation bar.</p><p>Urgent transitions are done the same way you've been setting a state before:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">const</span> <span class=\"token punctuation\">[</span>name<span class=\"token punctuation\">,</span> setName<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token function\">useState</span><span class=\"token punctuation\">(</span><span class=\"token string\">''</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token keyword\">function</span> <span class=\"token function\">handleChange</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">e</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n\t<span class=\"token function\">setName</span><span class=\"token punctuation\">(</span>e<span class=\"token punctuation\">.</span>target<span class=\"token punctuation\">.</span>value<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> <span class=\"token comment\">//urgent transition</span>\n<span class=\"token punctuation\">}</span></code></pre></div><h3 id=\"non-urgent-transitions\">Non-Urgent Transitions</h3><p>Non-urgent transitions are transitions that are ok to be delayed a little. For example, if the user is performing a search, it's ok for the results to appear not so instantly.</p><p>There are 2 ways to start a non-urgent transition. The first one is using the hook <code class=\"language-text\">useTransition</code>: </p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span>useTransition<span class=\"token punctuation\">,</span> useState<span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'react'</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token keyword\">export</span> <span class=\"token keyword\">default</span> <span class=\"token keyword\">function</span> <span class=\"token function\">MyApp</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">const</span> <span class=\"token punctuation\">[</span>results<span class=\"token punctuation\">,</span> setResults<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token function\">useState</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">const</span> <span class=\"token punctuation\">[</span>pending<span class=\"token punctuation\">,</span> startTransition<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token function\">useTransition</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    \n    <span class=\"token keyword\">function</span> <span class=\"token function\">handleChange</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">e</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">let</span> tempResults <span class=\"token operator\">=</span> <span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>\n        <span class=\"token operator\">...</span> <span class=\"token comment\">// set results from APIs</span>\n        <span class=\"token function\">startTransition</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n            <span class=\"token function\">setResults</span><span class=\"token punctuation\">(</span>tempResults<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div><p>The hook returns the boolean variable <code class=\"language-text\">pending</code> which indicates whether the transition is active or not. It can be used to show a loading component.</p><p>The hook also returns a function <code class=\"language-text\">startTransition</code> that accepts a callback function in which you set the state. The state will not be set immediately.</p><p>The second way to start a non-urgent transition is using the function <code class=\"language-text\">startTransition</code> imported directly from React:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span>startTransition<span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'react'</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token keyword\">export</span> <span class=\"token keyword\">default</span> <span class=\"token keyword\">function</span> <span class=\"token function\">MyApp</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">const</span> <span class=\"token punctuation\">[</span>results<span class=\"token punctuation\">,</span> setResults<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token function\">useState</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    \n    <span class=\"token keyword\">function</span> <span class=\"token function\">handleChange</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">e</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">let</span> tempResults <span class=\"token operator\">=</span> <span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>\n        <span class=\"token operator\">...</span> <span class=\"token comment\">// set results from APIs</span>\n        <span class=\"token function\">startTransition</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n            <span class=\"token function\">setResults</span><span class=\"token punctuation\">(</span>tempResults<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div><p>This approach does not give you access to a variable like <code class=\"language-text\">isPending</code> to check whether the transition is active or not.</p><p>This approach is mainly available for places in your code when you can't use hooks like <code class=\"language-text\">useTransition</code>.</p><h2 id=\"usage-example\">Usage Example</h2><p>In this example, you'll be creating a number input that accepts a large number of images to be shown. Then, random images will be retrieved using <a href=\"https://ngneat.github.io/falso/\">Falso</a>.</p><p>Start by creating a new React app if you don't have one available:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">npx create-react-app my-app</code></pre></div><p>Next, change into the directory <code class=\"language-text\">my-app</code>:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\"><span class=\"token builtin class-name\">cd</span> my-app</code></pre></div><p>Then, install the Falso library:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\"><span class=\"token function\">npm</span> i @ngneat/falso</code></pre></div><p>Now, open <code class=\"language-text\">src/App.js</code> and change it to the following:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">import</span> <span class=\"token string\">'./App.css'</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span> useState<span class=\"token punctuation\">,</span> useTransition <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'react'</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span> randImg <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'@ngneat/falso'</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token keyword\">function</span> <span class=\"token function\">App</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">const</span> <span class=\"token punctuation\">[</span>number<span class=\"token punctuation\">,</span> setNumber<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token function\">useState</span><span class=\"token punctuation\">(</span><span class=\"token number\">5000</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">const</span> <span class=\"token punctuation\">[</span>images<span class=\"token punctuation\">,</span> setImages<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token function\">useState</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span>\n  <span class=\"token keyword\">const</span> <span class=\"token punctuation\">[</span>isPending<span class=\"token punctuation\">,</span> startTransition<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token function\">useTransition</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token keyword\">function</span> <span class=\"token function\">showImages</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token comment\">//TODO add transition</span>\n  <span class=\"token punctuation\">}</span>\n\n  <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span>\n    <span class=\"token operator\">&#x3C;</span>div style<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span><span class=\"token punctuation\">{</span>\n      <span class=\"token literal-property property\">padding</span><span class=\"token operator\">:</span> <span class=\"token string\">'10px'</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">}</span><span class=\"token operator\">></span>\n      <span class=\"token operator\">&#x3C;</span>h1<span class=\"token operator\">></span>Images<span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>h1<span class=\"token operator\">></span>\n      <span class=\"token operator\">&#x3C;</span>div<span class=\"token operator\">></span>\n        <span class=\"token operator\">&#x3C;</span>label<span class=\"token operator\">></span>Number <span class=\"token keyword\">of</span> images<span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>label<span class=\"token operator\">></span>\n        <span class=\"token operator\">&#x3C;</span>input type<span class=\"token operator\">=</span><span class=\"token string\">\"number\"</span> min<span class=\"token operator\">=</span><span class=\"token string\">\"1\"</span> max<span class=\"token operator\">=</span><span class=\"token string\">\"10000\"</span> value<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span>number<span class=\"token punctuation\">}</span> onChange<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">e</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token function\">setNumber</span><span class=\"token punctuation\">(</span>e<span class=\"token punctuation\">.</span>target<span class=\"token punctuation\">.</span>value<span class=\"token punctuation\">)</span><span class=\"token punctuation\">}</span> style<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span><span class=\"token punctuation\">{</span>\n          <span class=\"token literal-property property\">display</span><span class=\"token operator\">:</span> <span class=\"token string\">'block'</span><span class=\"token punctuation\">,</span>\n          <span class=\"token literal-property property\">marginTop</span><span class=\"token operator\">:</span> <span class=\"token string\">'10px'</span><span class=\"token punctuation\">,</span>\n          <span class=\"token literal-property property\">width</span><span class=\"token operator\">:</span> <span class=\"token string\">'3rem'</span>\n        <span class=\"token punctuation\">}</span><span class=\"token punctuation\">}</span> <span class=\"token operator\">/</span><span class=\"token operator\">></span>\n        <span class=\"token operator\">&#x3C;</span>button type<span class=\"token operator\">=</span><span class=\"token string\">\"button\"</span> onClick<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span>showImages<span class=\"token punctuation\">}</span> style<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span><span class=\"token punctuation\">{</span><span class=\"token literal-property property\">marginTop</span><span class=\"token operator\">:</span> <span class=\"token string\">'10px'</span><span class=\"token punctuation\">}</span><span class=\"token punctuation\">}</span><span class=\"token operator\">></span>Show Images<span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>button<span class=\"token operator\">></span>\n      <span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>div<span class=\"token operator\">></span>\n      <span class=\"token operator\">&#x3C;</span>div<span class=\"token operator\">></span>\n        <span class=\"token operator\">&#x3C;</span>span<span class=\"token operator\">></span>Number selected<span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span>number<span class=\"token punctuation\">}</span><span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>span<span class=\"token operator\">></span><span class=\"token operator\">&#x3C;</span>br<span class=\"token operator\">/</span><span class=\"token operator\">></span>\n        <span class=\"token operator\">&#x3C;</span>span<span class=\"token operator\">></span>Results<span class=\"token operator\">:</span><span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>span<span class=\"token operator\">></span>\n        <span class=\"token punctuation\">{</span>isPending <span class=\"token operator\">&#x26;&#x26;</span> <span class=\"token operator\">&#x3C;</span>span<span class=\"token operator\">></span>Loading<span class=\"token operator\">...</span><span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>span<span class=\"token operator\">></span><span class=\"token punctuation\">}</span>\n        <span class=\"token punctuation\">{</span><span class=\"token operator\">!</span>isPending <span class=\"token operator\">&#x26;&#x26;</span> images<span class=\"token punctuation\">.</span>length <span class=\"token operator\">></span> <span class=\"token number\">0</span> <span class=\"token operator\">&#x26;&#x26;</span> images<span class=\"token punctuation\">}</span>\n      <span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>div<span class=\"token operator\">></span>\n    <span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>div<span class=\"token operator\">></span>\n  <span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">export</span> <span class=\"token keyword\">default</span> App<span class=\"token punctuation\">;</span>\n</code></pre></div><p>You first create 2 state variables <code class=\"language-text\">number</code> and <code class=\"language-text\">images</code>. You also use <code class=\"language-text\">useTransition</code> which gives you access to <code class=\"language-text\">isPending</code> and <code class=\"language-text\">startTransition</code>.</p><p>In the returned JSX, you show a number input and a button that will later retrieve the images on click.</p><p>Below the input and button, the number entered by the user in the input will be shown. Notice that in the <code class=\"language-text\">onChange</code> event handler for the input the name is updated <strong>urgently. </strong>This will show the number instantly as it is updated by the user.</p><p>Let's test it out now. Run the website server:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\"><span class=\"token function\">npm</span> start</code></pre></div><p>This will open the website in your browser. If you try to update the input, you'll notice that the number displayed below it will update instantly.</p><figure class=\"kg-card kg-video-card\"><div class=\"kg-video-container\"><video src=\"https://backend.shahednasser.com/content/media/2022/04/Screen-Recording-2022-04-23-at-3.45.38-PM.mp4\" poster=\"https://img.spacergif.org/v1/798x692/0a/spacer.png\" width=\"798\" height=\"692\" playsinline preload=\"metadata\" style=\"background: transparent url(&#x27;https://backend.shahednasser.com/content/images/2022/04/media-thumbnail-ember409.jpg&#x27;) 50% 50% / cover no-repeat;\"></video><div class=\"kg-video-overlay\"><button class=\"kg-video-large-play-icon\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M23.14 10.608 2.253.164A1.559 1.559 0 0 0 0 1.557v20.887a1.558 1.558 0 0 0 2.253 1.392L23.14 13.393a1.557 1.557 0 0 0 0-2.785Z\"></path></svg></button></div><div class=\"kg-video-player-container\"><div class=\"kg-video-player\"><button class=\"kg-video-play-icon\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M23.14 10.608 2.253.164A1.559 1.559 0 0 0 0 1.557v20.887a1.558 1.558 0 0 0 2.253 1.392L23.14 13.393a1.557 1.557 0 0 0 0-2.785Z\"></path></svg></button><button class=\"kg-video-pause-icon kg-video-hide\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><rect x=\"3\" y=\"1\" width=\"7\" height=\"22\" rx=\"1.5\" ry=\"1.5\"></rect><rect x=\"14\" y=\"1\" width=\"7\" height=\"22\" rx=\"1.5\" ry=\"1.5\"></rect></svg></button><span class=\"kg-video-current-time\">0:00</span><div class=\"kg-video-time\">/<span class=\"kg-video-duration\"></span></div><input type=\"range\" class=\"kg-video-seek-slider\" max=\"100\" value=\"0\"><button class=\"kg-video-playback-rate\">1×</button><button class=\"kg-video-unmute-icon\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M15.189 2.021a9.728 9.728 0 0 0-7.924 4.85.249.249 0 0 1-.221.133H5.25a3 3 0 0 0-3 3v2a3 3 0 0 0 3 3h1.794a.249.249 0 0 1 .221.133 9.73 9.73 0 0 0 7.924 4.85h.06a1 1 0 0 0 1-1V3.02a1 1 0 0 0-1.06-.998Z\"></path></svg></button><button class=\"kg-video-mute-icon kg-video-hide\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M16.177 4.3a.248.248 0 0 0 .073-.176v-1.1a1 1 0 0 0-1.061-1 9.728 9.728 0 0 0-7.924 4.85.249.249 0 0 1-.221.133H5.25a3 3 0 0 0-3 3v2a3 3 0 0 0 3 3h.114a.251.251 0 0 0 .177-.073ZM23.707 1.706A1 1 0 0 0 22.293.292l-22 22a1 1 0 0 0 0 1.414l.009.009a1 1 0 0 0 1.405-.009l6.63-6.631A.251.251 0 0 1 8.515 17a.245.245 0 0 1 .177.075 10.081 10.081 0 0 0 6.5 2.92 1 1 0 0 0 1.061-1V9.266a.247.247 0 0 1 .073-.176Z\"></path></svg></button><input type=\"range\" class=\"kg-video-volume-slider\" max=\"100\" value=\"100\"></div></div></div></figure><p>Now, let's test the non-urgent transition. In <code class=\"language-text\">showImages</code> replace the <code class=\"language-text\">TODO</code> with the following code:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">const</span> imgSources <span class=\"token operator\">=</span> <span class=\"token function\">randImg</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span><span class=\"token literal-property property\">length</span><span class=\"token operator\">:</span> number<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">map</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">url<span class=\"token punctuation\">,</span> index</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token operator\">&#x3C;</span>img src<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span><span class=\"token template-string\"><span class=\"token template-punctuation string\">`</span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${</span>url<span class=\"token interpolation-punctuation punctuation\">}</span></span><span class=\"token string\">?v=</span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${</span>index<span class=\"token interpolation-punctuation punctuation\">}</span></span><span class=\"token template-punctuation string\">`</span></span><span class=\"token punctuation\">}</span> key<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span>index<span class=\"token punctuation\">}</span> <span class=\"token operator\">/</span><span class=\"token operator\">></span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token function\">startTransition</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n\t<span class=\"token function\">setImages</span><span class=\"token punctuation\">(</span>imgSources<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span></code></pre></div><p>This will get the images using the <code class=\"language-text\">falso</code> library and inside <code class=\"language-text\">startTransition</code> with set the <code class=\"language-text\">images</code> state variable.</p><p>Notice that in the returned JSX of the function we use <code class=\"language-text\">isPending</code> to indicate whether to show \"Loading...\" or not.</p><p>If you try clicking on the button now, the \"Loading...\" text will show first, and then the images will be shown gradually.</p><figure class=\"kg-card kg-video-card\"><div class=\"kg-video-container\"><video src=\"https://backend.shahednasser.com/content/media/2022/04/Screen-Recording-2022-04-23-at-4.01.34-PM.mp4\" poster=\"https://img.spacergif.org/v1/794x896/0a/spacer.png\" width=\"794\" height=\"896\" playsinline preload=\"metadata\" style=\"background: transparent url(&#x27;https://backend.shahednasser.com/content/images/2022/04/media-thumbnail-ember441.jpg&#x27;) 50% 50% / cover no-repeat;\"></video><div class=\"kg-video-overlay\"><button class=\"kg-video-large-play-icon\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M23.14 10.608 2.253.164A1.559 1.559 0 0 0 0 1.557v20.887a1.558 1.558 0 0 0 2.253 1.392L23.14 13.393a1.557 1.557 0 0 0 0-2.785Z\"></path></svg></button></div><div class=\"kg-video-player-container\"><div class=\"kg-video-player\"><button class=\"kg-video-play-icon\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M23.14 10.608 2.253.164A1.559 1.559 0 0 0 0 1.557v20.887a1.558 1.558 0 0 0 2.253 1.392L23.14 13.393a1.557 1.557 0 0 0 0-2.785Z\"></path></svg></button><button class=\"kg-video-pause-icon kg-video-hide\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><rect x=\"3\" y=\"1\" width=\"7\" height=\"22\" rx=\"1.5\" ry=\"1.5\"></rect><rect x=\"14\" y=\"1\" width=\"7\" height=\"22\" rx=\"1.5\" ry=\"1.5\"></rect></svg></button><span class=\"kg-video-current-time\">0:00</span><div class=\"kg-video-time\">/<span class=\"kg-video-duration\"></span></div><input type=\"range\" class=\"kg-video-seek-slider\" max=\"100\" value=\"0\"><button class=\"kg-video-playback-rate\">1×</button><button class=\"kg-video-unmute-icon\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M15.189 2.021a9.728 9.728 0 0 0-7.924 4.85.249.249 0 0 1-.221.133H5.25a3 3 0 0 0-3 3v2a3 3 0 0 0 3 3h1.794a.249.249 0 0 1 .221.133 9.73 9.73 0 0 0 7.924 4.85h.06a1 1 0 0 0 1-1V3.02a1 1 0 0 0-1.06-.998Z\"></path></svg></button><button class=\"kg-video-mute-icon kg-video-hide\"><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M16.177 4.3a.248.248 0 0 0 .073-.176v-1.1a1 1 0 0 0-1.061-1 9.728 9.728 0 0 0-7.924 4.85.249.249 0 0 1-.221.133H5.25a3 3 0 0 0-3 3v2a3 3 0 0 0 3 3h.114a.251.251 0 0 0 .177-.073ZM23.707 1.706A1 1 0 0 0 22.293.292l-22 22a1 1 0 0 0 0 1.414l.009.009a1 1 0 0 0 1.405-.009l6.63-6.631A.251.251 0 0 1 8.515 17a.245.245 0 0 1 .177.075 10.081 10.081 0 0 0 6.5 2.92 1 1 0 0 0 1.061-1V9.266a.247.247 0 0 1 .073-.176Z\"></path></svg></button><input type=\"range\" class=\"kg-video-volume-slider\" max=\"100\" value=\"100\"></div></div></div></figure><h2 id=\"conclusion\">Conclusion</h2><p>Transitions in React 18 allow you to optimize your user experience, especially for tasks or features that require some time to load. You can now use Transitions in React 18 to differentiate between instate updates and updates that can be delayed, and show in the UI any necessary loading more efficiently for those that require more time.</p>","htmlAst":{"type":"root","children":[{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"a","properties":{"href":"https://reactjs.org/blog/2022/03/29/react-v18.html"},"children":[{"type":"text","value":"React 18 came out at the end of March"}]},{"type":"text","value":" with a bundle of new features. One of these new features is Transitions."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"In this tutorial, you'll learn more about Transitions in React 18 and see them in action."}]},{"type":"element","tagName":"h2","properties":{"id":"definition"},"children":[{"type":"text","value":"Definition"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"You have 2 types of transitions. Urgent transitions and non-urgent transitions."}]},{"type":"element","tagName":"h3","properties":{"id":"urgent-transitions"},"children":[{"type":"text","value":"Urgent Transitions"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Urgent transitions are transitions that the user needs to see instantly. For example, if the user changes their profile name and saves it, they should be able to see the change in the displayed profile name in the navigation bar."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Urgent transitions are done the same way you've been setting a state before:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"["}]},{"type":"text","value":"name"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" setName"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"]"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"useState"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"''"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"function"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"handleChange"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"e"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n\t"},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"setName"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"e"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"target"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"value"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"//urgent transition"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]}]}]}]},{"type":"element","tagName":"h3","properties":{"id":"non-urgent-transitions"},"children":[{"type":"text","value":"Non-Urgent Transitions"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Non-urgent transitions are transitions that are ok to be delayed a little. For example, if the user is performing a search, it's ok for the results to appear not so instantly."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"There are 2 ways to start a non-urgent transition. The first one is using the hook "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"useTransition"}]},{"type":"text","value":": "}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"import"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"useTransition"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" useState"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"from"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'react'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"export"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"default"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"function"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"MyApp"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"["}]},{"type":"text","value":"results"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" setResults"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"]"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"useState"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"["}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"]"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"["}]},{"type":"text","value":"pending"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" startTransition"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"]"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"useTransition"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n    \n    "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"function"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"handleChange"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"e"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"let"}]},{"type":"text","value":" tempResults "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"["}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"]"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"..."}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"// set results from APIs"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"startTransition"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n            "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"setResults"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"tempResults"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"The hook returns the boolean variable "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"pending"}]},{"type":"text","value":" which indicates whether the transition is active or not. It can be used to show a loading component."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"The hook also returns a function "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"startTransition"}]},{"type":"text","value":" that accepts a callback function in which you set the state. The state will not be set immediately."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"The second way to start a non-urgent transition is using the function "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"startTransition"}]},{"type":"text","value":" imported directly from React:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"import"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"startTransition"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"from"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'react'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"export"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"default"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"function"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"MyApp"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"["}]},{"type":"text","value":"results"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" setResults"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"]"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"useState"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"["}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"]"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n    \n    "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"function"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"handleChange"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"e"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"let"}]},{"type":"text","value":" tempResults "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"["}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"]"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"..."}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"// set results from APIs"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"startTransition"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n            "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"setResults"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"tempResults"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"This approach does not give you access to a variable like "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"isPending"}]},{"type":"text","value":" to check whether the transition is active or not."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"This approach is mainly available for places in your code when you can't use hooks like "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"useTransition"}]},{"type":"text","value":"."}]},{"type":"element","tagName":"h2","properties":{"id":"usage-example"},"children":[{"type":"text","value":"Usage Example"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"In this example, you'll be creating a number input that accepts a large number of images to be shown. Then, random images will be retrieved using "},{"type":"element","tagName":"a","properties":{"href":"https://ngneat.github.io/falso/"},"children":[{"type":"text","value":"Falso"}]},{"type":"text","value":"."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Start by creating a new React app if you don't have one available:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"bash"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-bash"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-bash"]},"children":[{"type":"text","value":"npx create-react-app my-app"}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Next, change into the directory "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"my-app"}]},{"type":"text","value":":"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"bash"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-bash"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-bash"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","builtin","class-name"]},"children":[{"type":"text","value":"cd"}]},{"type":"text","value":" my-app"}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Then, install the Falso library:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"bash"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-bash"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-bash"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"npm"}]},{"type":"text","value":" i @ngneat/falso"}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Now, open "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"src/App.js"}]},{"type":"text","value":" and change it to the following:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"import"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'./App.css'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"import"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" useState"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" useTransition "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"from"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'react'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"import"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" randImg "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"from"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'@ngneat/falso'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"function"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"App"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"["}]},{"type":"text","value":"number"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" setNumber"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"]"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"useState"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"5000"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"["}]},{"type":"text","value":"images"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" setImages"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"]"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"useState"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"["}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"]"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"["}]},{"type":"text","value":"isPending"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" startTransition"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"]"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"useTransition"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n\n  "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"function"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"showImages"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"//TODO add transition"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n\n  "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"div style"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"padding"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'10px'"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"h1"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"Images"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"h1"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"div"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"label"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"Number "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"of"}]},{"type":"text","value":" images"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"label"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"input type"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"number\""}]},{"type":"text","value":" min"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"1\""}]},{"type":"text","value":" max"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"10000\""}]},{"type":"text","value":" value"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"number"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" onChange"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"e"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"setNumber"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"e"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"target"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"value"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" style"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n          "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"display"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'block'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n          "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"marginTop"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'10px'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n          "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"width"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'3rem'"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"button type"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"button\""}]},{"type":"text","value":" onClick"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"showImages"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" style"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"marginTop"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'10px'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"Show Images"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"button"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"div"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"div"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"span"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"Number selected"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"number"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"span"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"br"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"span"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"Results"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"span"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"isPending "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"&&"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"span"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"Loading"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"..."}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"span"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"!"}]},{"type":"text","value":"isPending "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"&&"}]},{"type":"text","value":" images"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"length "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"0"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"&&"}]},{"type":"text","value":" images"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"div"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"div"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"export"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"default"}]},{"type":"text","value":" App"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n"}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"You first create 2 state variables "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"number"}]},{"type":"text","value":" and "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"images"}]},{"type":"text","value":". You also use "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"useTransition"}]},{"type":"text","value":" which gives you access to "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"isPending"}]},{"type":"text","value":" and "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"startTransition"}]},{"type":"text","value":"."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"In the returned JSX, you show a number input and a button that will later retrieve the images on click."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Below the input and button, the number entered by the user in the input will be shown. Notice that in the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"onChange"}]},{"type":"text","value":" event handler for the input the name is updated "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"urgently. "}]},{"type":"text","value":"This will show the number instantly as it is updated by the user."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Let's test it out now. Run the website server:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"bash"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-bash"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-bash"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"npm"}]},{"type":"text","value":" start"}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"This will open the website in your browser. If you try to update the input, you'll notice that the number displayed below it will update instantly."}]},{"type":"element","tagName":"figure","properties":{"className":["kg-card","kg-video-card"]},"children":[{"type":"element","tagName":"div","properties":{"className":["kg-video-container"]},"children":[{"type":"element","tagName":"video","properties":{"src":"https://backend.shahednasser.com/content/media/2022/04/Screen-Recording-2022-04-23-at-3.45.38-PM.mp4","poster":"https://img.spacergif.org/v1/798x692/0a/spacer.png","width":798,"height":692,"playsInline":true,"preload":"metadata","style":"background: transparent url('https://backend.shahednasser.com/content/images/2022/04/media-thumbnail-ember409.jpg') 50% 50% / cover no-repeat;"},"children":[]},{"type":"element","tagName":"div","properties":{"className":["kg-video-overlay"]},"children":[{"type":"element","tagName":"button","properties":{"className":["kg-video-large-play-icon"]},"children":[{"type":"element","tagName":"svg","properties":{"xmlns":"http://www.w3.org/2000/svg","viewBox":"0 0 24 24"},"children":[{"type":"element","tagName":"path","properties":{"d":"M23.14 10.608 2.253.164A1.559 1.559 0 0 0 0 1.557v20.887a1.558 1.558 0 0 0 2.253 1.392L23.14 13.393a1.557 1.557 0 0 0 0-2.785Z"},"children":[]}]}]}]},{"type":"element","tagName":"div","properties":{"className":["kg-video-player-container"]},"children":[{"type":"element","tagName":"div","properties":{"className":["kg-video-player"]},"children":[{"type":"element","tagName":"button","properties":{"className":["kg-video-play-icon"]},"children":[{"type":"element","tagName":"svg","properties":{"xmlns":"http://www.w3.org/2000/svg","viewBox":"0 0 24 24"},"children":[{"type":"element","tagName":"path","properties":{"d":"M23.14 10.608 2.253.164A1.559 1.559 0 0 0 0 1.557v20.887a1.558 1.558 0 0 0 2.253 1.392L23.14 13.393a1.557 1.557 0 0 0 0-2.785Z"},"children":[]}]}]},{"type":"element","tagName":"button","properties":{"className":["kg-video-pause-icon","kg-video-hide"]},"children":[{"type":"element","tagName":"svg","properties":{"xmlns":"http://www.w3.org/2000/svg","viewBox":"0 0 24 24"},"children":[{"type":"element","tagName":"rect","properties":{"x":"3","y":"1","width":7,"height":22,"rx":"1.5","ry":"1.5"},"children":[]},{"type":"element","tagName":"rect","properties":{"x":"14","y":"1","width":7,"height":22,"rx":"1.5","ry":"1.5"},"children":[]}]}]},{"type":"element","tagName":"span","properties":{"className":["kg-video-current-time"]},"children":[{"type":"text","value":"0:00"}]},{"type":"element","tagName":"div","properties":{"className":["kg-video-time"]},"children":[{"type":"text","value":"/"},{"type":"element","tagName":"span","properties":{"className":["kg-video-duration"]},"children":[]}]},{"type":"element","tagName":"input","properties":{"type":"range","className":["kg-video-seek-slider"],"max":"100","value":"0"},"children":[]},{"type":"element","tagName":"button","properties":{"className":["kg-video-playback-rate"]},"children":[{"type":"text","value":"1×"}]},{"type":"element","tagName":"button","properties":{"className":["kg-video-unmute-icon"]},"children":[{"type":"element","tagName":"svg","properties":{"xmlns":"http://www.w3.org/2000/svg","viewBox":"0 0 24 24"},"children":[{"type":"element","tagName":"path","properties":{"d":"M15.189 2.021a9.728 9.728 0 0 0-7.924 4.85.249.249 0 0 1-.221.133H5.25a3 3 0 0 0-3 3v2a3 3 0 0 0 3 3h1.794a.249.249 0 0 1 .221.133 9.73 9.73 0 0 0 7.924 4.85h.06a1 1 0 0 0 1-1V3.02a1 1 0 0 0-1.06-.998Z"},"children":[]}]}]},{"type":"element","tagName":"button","properties":{"className":["kg-video-mute-icon","kg-video-hide"]},"children":[{"type":"element","tagName":"svg","properties":{"xmlns":"http://www.w3.org/2000/svg","viewBox":"0 0 24 24"},"children":[{"type":"element","tagName":"path","properties":{"d":"M16.177 4.3a.248.248 0 0 0 .073-.176v-1.1a1 1 0 0 0-1.061-1 9.728 9.728 0 0 0-7.924 4.85.249.249 0 0 1-.221.133H5.25a3 3 0 0 0-3 3v2a3 3 0 0 0 3 3h.114a.251.251 0 0 0 .177-.073ZM23.707 1.706A1 1 0 0 0 22.293.292l-22 22a1 1 0 0 0 0 1.414l.009.009a1 1 0 0 0 1.405-.009l6.63-6.631A.251.251 0 0 1 8.515 17a.245.245 0 0 1 .177.075 10.081 10.081 0 0 0 6.5 2.92 1 1 0 0 0 1.061-1V9.266a.247.247 0 0 1 .073-.176Z"},"children":[]}]}]},{"type":"element","tagName":"input","properties":{"type":"range","className":["kg-video-volume-slider"],"max":"100","value":"100"},"children":[]}]}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Now, let's test the non-urgent transition. In "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"showImages"}]},{"type":"text","value":" replace the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"TODO"}]},{"type":"text","value":" with the following code:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" imgSources "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"randImg"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"length"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" number"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"map"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"url"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" index"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"img src"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"element","tagName":"span","properties":{"className":["token","template-string"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","template-punctuation","string"]},"children":[{"type":"text","value":"`"}]},{"type":"element","tagName":"span","properties":{"className":["token","interpolation"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","interpolation-punctuation","punctuation"]},"children":[{"type":"text","value":"${"}]},{"type":"text","value":"url"},{"type":"element","tagName":"span","properties":{"className":["token","interpolation-punctuation","punctuation"]},"children":[{"type":"text","value":"}"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"?v="}]},{"type":"element","tagName":"span","properties":{"className":["token","interpolation"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","interpolation-punctuation","punctuation"]},"children":[{"type":"text","value":"${"}]},{"type":"text","value":"index"},{"type":"element","tagName":"span","properties":{"className":["token","interpolation-punctuation","punctuation"]},"children":[{"type":"text","value":"}"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","template-punctuation","string"]},"children":[{"type":"text","value":"`"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" key"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"index"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"startTransition"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n\t"},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"setImages"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"imgSources"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"This will get the images using the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"falso"}]},{"type":"text","value":" library and inside "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"startTransition"}]},{"type":"text","value":" with set the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"images"}]},{"type":"text","value":" state variable."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Notice that in the returned JSX of the function we use "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"isPending"}]},{"type":"text","value":" to indicate whether to show \"Loading...\" or not."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"If you try clicking on the button now, the \"Loading...\" text will show first, and then the images will be shown gradually."}]},{"type":"element","tagName":"figure","properties":{"className":["kg-card","kg-video-card"]},"children":[{"type":"element","tagName":"div","properties":{"className":["kg-video-container"]},"children":[{"type":"element","tagName":"video","properties":{"src":"https://backend.shahednasser.com/content/media/2022/04/Screen-Recording-2022-04-23-at-4.01.34-PM.mp4","poster":"https://img.spacergif.org/v1/794x896/0a/spacer.png","width":794,"height":896,"playsInline":true,"preload":"metadata","style":"background: transparent url('https://backend.shahednasser.com/content/images/2022/04/media-thumbnail-ember441.jpg') 50% 50% / cover no-repeat;"},"children":[]},{"type":"element","tagName":"div","properties":{"className":["kg-video-overlay"]},"children":[{"type":"element","tagName":"button","properties":{"className":["kg-video-large-play-icon"]},"children":[{"type":"element","tagName":"svg","properties":{"xmlns":"http://www.w3.org/2000/svg","viewBox":"0 0 24 24"},"children":[{"type":"element","tagName":"path","properties":{"d":"M23.14 10.608 2.253.164A1.559 1.559 0 0 0 0 1.557v20.887a1.558 1.558 0 0 0 2.253 1.392L23.14 13.393a1.557 1.557 0 0 0 0-2.785Z"},"children":[]}]}]}]},{"type":"element","tagName":"div","properties":{"className":["kg-video-player-container"]},"children":[{"type":"element","tagName":"div","properties":{"className":["kg-video-player"]},"children":[{"type":"element","tagName":"button","properties":{"className":["kg-video-play-icon"]},"children":[{"type":"element","tagName":"svg","properties":{"xmlns":"http://www.w3.org/2000/svg","viewBox":"0 0 24 24"},"children":[{"type":"element","tagName":"path","properties":{"d":"M23.14 10.608 2.253.164A1.559 1.559 0 0 0 0 1.557v20.887a1.558 1.558 0 0 0 2.253 1.392L23.14 13.393a1.557 1.557 0 0 0 0-2.785Z"},"children":[]}]}]},{"type":"element","tagName":"button","properties":{"className":["kg-video-pause-icon","kg-video-hide"]},"children":[{"type":"element","tagName":"svg","properties":{"xmlns":"http://www.w3.org/2000/svg","viewBox":"0 0 24 24"},"children":[{"type":"element","tagName":"rect","properties":{"x":"3","y":"1","width":7,"height":22,"rx":"1.5","ry":"1.5"},"children":[]},{"type":"element","tagName":"rect","properties":{"x":"14","y":"1","width":7,"height":22,"rx":"1.5","ry":"1.5"},"children":[]}]}]},{"type":"element","tagName":"span","properties":{"className":["kg-video-current-time"]},"children":[{"type":"text","value":"0:00"}]},{"type":"element","tagName":"div","properties":{"className":["kg-video-time"]},"children":[{"type":"text","value":"/"},{"type":"element","tagName":"span","properties":{"className":["kg-video-duration"]},"children":[]}]},{"type":"element","tagName":"input","properties":{"type":"range","className":["kg-video-seek-slider"],"max":"100","value":"0"},"children":[]},{"type":"element","tagName":"button","properties":{"className":["kg-video-playback-rate"]},"children":[{"type":"text","value":"1×"}]},{"type":"element","tagName":"button","properties":{"className":["kg-video-unmute-icon"]},"children":[{"type":"element","tagName":"svg","properties":{"xmlns":"http://www.w3.org/2000/svg","viewBox":"0 0 24 24"},"children":[{"type":"element","tagName":"path","properties":{"d":"M15.189 2.021a9.728 9.728 0 0 0-7.924 4.85.249.249 0 0 1-.221.133H5.25a3 3 0 0 0-3 3v2a3 3 0 0 0 3 3h1.794a.249.249 0 0 1 .221.133 9.73 9.73 0 0 0 7.924 4.85h.06a1 1 0 0 0 1-1V3.02a1 1 0 0 0-1.06-.998Z"},"children":[]}]}]},{"type":"element","tagName":"button","properties":{"className":["kg-video-mute-icon","kg-video-hide"]},"children":[{"type":"element","tagName":"svg","properties":{"xmlns":"http://www.w3.org/2000/svg","viewBox":"0 0 24 24"},"children":[{"type":"element","tagName":"path","properties":{"d":"M16.177 4.3a.248.248 0 0 0 .073-.176v-1.1a1 1 0 0 0-1.061-1 9.728 9.728 0 0 0-7.924 4.85.249.249 0 0 1-.221.133H5.25a3 3 0 0 0-3 3v2a3 3 0 0 0 3 3h.114a.251.251 0 0 0 .177-.073ZM23.707 1.706A1 1 0 0 0 22.293.292l-22 22a1 1 0 0 0 0 1.414l.009.009a1 1 0 0 0 1.405-.009l6.63-6.631A.251.251 0 0 1 8.515 17a.245.245 0 0 1 .177.075 10.081 10.081 0 0 0 6.5 2.92 1 1 0 0 0 1.061-1V9.266a.247.247 0 0 1 .073-.176Z"},"children":[]}]}]},{"type":"element","tagName":"input","properties":{"type":"range","className":["kg-video-volume-slider"],"max":"100","value":"100"},"children":[]}]}]}]}]},{"type":"element","tagName":"h2","properties":{"id":"conclusion"},"children":[{"type":"text","value":"Conclusion"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Transitions in React 18 allow you to optimize your user experience, especially for tasks or features that require some time to load. You can now use Transitions in React 18 to differentiate between instate updates and updates that can be delayed, and show in the UI any necessary loading more efficiently for those that require more time."}]}],"data":{"quirksMode":false}},"tableOfContents":[{"id":"definition","heading":"Definition","items":[{"id":"urgent-transitions","heading":"Urgent Transitions"},{"id":"non-urgent-transitions","heading":"Non-Urgent Transitions"}]},{"id":"usage-example","heading":"Usage Example"},{"id":"conclusion","heading":"Conclusion"}]},"featureImageSharp":{"base":"How-to-use-Transitions-in-React-18-2.jpg","publicURL":"/static/a653d678a3e8e1cde9337a2091d4db0c/How-to-use-Transitions-in-React-18-2.jpg","imageMeta":{"width":1560,"height":876},"childImageSharp":{"fluid":{"base64":"data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAALABQDASIAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAAAAECBf/EABQBAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhADEAAAAe60Io//xAAWEAEBAQAAAAAAAAAAAAAAAAAhACD/2gAIAQEAAQUCZz//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/AT//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/AT//xAAWEAEBAQAAAAAAAAAAAAAAAAAxACD/2gAIAQEABj8CIz//xAAZEAACAwEAAAAAAAAAAAAAAAAAEQEh8SD/2gAIAQEAAT8heg9CGrrj/9oADAMBAAIAAwAAABAjz//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQMBAT8QP//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQIBAT8QP//EABsQAAICAwEAAAAAAAAAAAAAAAERADEgIWFR/9oACAEBAAE/EHEqpW7dnPJkwN43h//Z","aspectRatio":1.7857142857142858,"src":"/static/a653d678a3e8e1cde9337a2091d4db0c/ea4ab/How-to-use-Transitions-in-React-18-2.jpg","srcSet":"/static/a653d678a3e8e1cde9337a2091d4db0c/477ba/How-to-use-Transitions-in-React-18-2.jpg 175w,\n/static/a653d678a3e8e1cde9337a2091d4db0c/06776/How-to-use-Transitions-in-React-18-2.jpg 350w,\n/static/a653d678a3e8e1cde9337a2091d4db0c/ea4ab/How-to-use-Transitions-in-React-18-2.jpg 700w,\n/static/a653d678a3e8e1cde9337a2091d4db0c/3055e/How-to-use-Transitions-in-React-18-2.jpg 1050w,\n/static/a653d678a3e8e1cde9337a2091d4db0c/eff08/How-to-use-Transitions-in-React-18-2.jpg 1400w,\n/static/a653d678a3e8e1cde9337a2091d4db0c/81a53/How-to-use-Transitions-in-React-18-2.jpg 1560w","srcWebp":"/static/a653d678a3e8e1cde9337a2091d4db0c/89afa/How-to-use-Transitions-in-React-18-2.webp","srcSetWebp":"/static/a653d678a3e8e1cde9337a2091d4db0c/9fca7/How-to-use-Transitions-in-React-18-2.webp 175w,\n/static/a653d678a3e8e1cde9337a2091d4db0c/37a4e/How-to-use-Transitions-in-React-18-2.webp 350w,\n/static/a653d678a3e8e1cde9337a2091d4db0c/89afa/How-to-use-Transitions-in-React-18-2.webp 700w,\n/static/a653d678a3e8e1cde9337a2091d4db0c/78e7a/How-to-use-Transitions-in-React-18-2.webp 1050w,\n/static/a653d678a3e8e1cde9337a2091d4db0c/03d34/How-to-use-Transitions-in-React-18-2.webp 1400w,\n/static/a653d678a3e8e1cde9337a2091d4db0c/f5845/How-to-use-Transitions-in-React-18-2.webp 1560w","sizes":"(max-width: 700px) 100vw, 700px"}}}}},{"node":{"id":"Ghost__Post__6235d3ec1594e705e60e186f","title":"How to Create and Validate Forms in React using Formik and Yup","slug":"how-to-create-and-validate-forms-in-react-using-formik-and-yup","featured":true,"feature_image":"https://backend.shahednasser.com/content/images/2022/03/How-to-Create-and-Validate-Forms-in-React-using-Formik-and-Yup.webp","excerpt":"In this tutorial, you'll learn how creating and validating forms can be simpler in React using Formik and Yup.","custom_excerpt":"In this tutorial, you'll learn how creating and validating forms can be simpler in React using Formik and Yup.","visibility":"public","created_at_pretty":"19 Mar 2022","published_at_pretty":"21 Mar 2022","updated_at_pretty":"27 Mar 2022","created_at":"2022-03-19T13:00:28.000+00:00","published_at":"2022-03-21T10:55:46.000+00:00","updated_at":"2022-03-27T10:36:28.000+00:00","meta_title":null,"meta_description":null,"og_description":null,"og_image":null,"og_title":null,"twitter_description":null,"twitter_image":null,"twitter_title":null,"authors":[{"slug":"shahed","url":"https://backend.shahednasser.com/author/shahed/","name":"Shahed Nasser","bio":null,"cover_image":null,"profile_image":"https://backend.shahednasser.com/content/images/2022/03/IMG_0591.jpg","location":null,"website":null,"twitter":null,"facebook":null,"meta_title":null,"meta_description":null,"coverImageSharp":null,"profileImageSharp":null}],"primary_author":{"slug":"shahed","url":"https://backend.shahednasser.com/author/shahed/","name":"Shahed Nasser","bio":null,"cover_image":null,"profile_image":"https://backend.shahednasser.com/content/images/2022/03/IMG_0591.jpg","location":null,"website":null,"twitter":null,"facebook":null,"meta_title":null,"meta_description":null,"coverImageSharp":null,"profileImageSharp":{"base":"IMG_0591.jpg","publicURL":"/static/ceb49c3c631485453e71e00d7f84b069/IMG_0591.jpg","imageMeta":{"width":1182,"height":1179},"childImageSharp":{"fluid":{"base64":"data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAUABQDASIAAhEBAxEB/8QAGAABAQEBAQAAAAAAAAAAAAAAAAMEAQL/xAAWAQEBAQAAAAAAAAAAAAAAAAADBAL/2gAMAwEAAhADEAAAAdXiFM6i0CohUWXoKn//xAAcEAACAgIDAAAAAAAAAAAAAAACAwESBBEhM0H/2gAIAQEAAQUCWySE3WEr7SzbXjAj4iKty+sOQ//EABYRAQEBAAAAAAAAAAAAAAAAAAERIP/aAAgBAwEBPwEhj//EABQRAQAAAAAAAAAAAAAAAAAAACD/2gAIAQIBAT8BH//EAB4QAAIBBAMBAAAAAAAAAAAAAAABIRESMUECECJx/9oACAEBAAY/ApVGWvOjzgtUwLlTZA0sdL4f/8QAHBAAAwACAwEAAAAAAAAAAAAAAAERITFBkbHB/9oACAEBAAE/IahkCy+N2GwZpjQiJHJCspUFY0QrSi+HqiW2rgf/2gAMAwEAAgADAAAAEPw3/wD/xAAYEQEBAAMAAAAAAAAAAAAAAAAAARExQf/aAAgBAwEBPxCtjDqP/8QAFxEBAQEBAAAAAAAAAAAAAAAAAQAxEf/aAAgBAgEBPxBFus6Tt//EAB8QAQEAAgIBBQAAAAAAAAAAAAERACExQWFRcYGR0f/aAAgBAQABPxAuaBPPzkO1wyX7F4wkwXanfZrFQgeqE9JgS14vVOvrERIJomVBKwt2jebAeP0yVa8h1n//2Q==","aspectRatio":1,"src":"/static/ceb49c3c631485453e71e00d7f84b069/31709/IMG_0591.jpg","srcSet":"/static/ceb49c3c631485453e71e00d7f84b069/f340b/IMG_0591.jpg 28w,\n/static/ceb49c3c631485453e71e00d7f84b069/22d64/IMG_0591.jpg 55w,\n/static/ceb49c3c631485453e71e00d7f84b069/31709/IMG_0591.jpg 110w,\n/static/ceb49c3c631485453e71e00d7f84b069/aa249/IMG_0591.jpg 165w,\n/static/ceb49c3c631485453e71e00d7f84b069/0dc33/IMG_0591.jpg 220w,\n/static/ceb49c3c631485453e71e00d7f84b069/d8257/IMG_0591.jpg 1182w","srcWebp":"/static/ceb49c3c631485453e71e00d7f84b069/8678c/IMG_0591.webp","srcSetWebp":"/static/ceb49c3c631485453e71e00d7f84b069/59cda/IMG_0591.webp 28w,\n/static/ceb49c3c631485453e71e00d7f84b069/7da75/IMG_0591.webp 55w,\n/static/ceb49c3c631485453e71e00d7f84b069/8678c/IMG_0591.webp 110w,\n/static/ceb49c3c631485453e71e00d7f84b069/f282e/IMG_0591.webp 165w,\n/static/ceb49c3c631485453e71e00d7f84b069/a7b21/IMG_0591.webp 220w,\n/static/ceb49c3c631485453e71e00d7f84b069/63099/IMG_0591.webp 1182w","sizes":"(max-width: 110px) 100vw, 110px"}}}},"primary_tag":{"slug":"react","url":"https://backend.shahednasser.com/tag/react/","name":"React","visibility":"public","feature_image":"https://images.unsplash.com/photo-1581276879432-15e50529f34b?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=MnwxMTc3M3wwfDF8c2VhcmNofDN8fHJlYWN0fGVufDB8fHx8MTYyMjYzMzI0MA&ixlib=rb-1.2.1&q=80&w=2000","description":"Learn more about React through tutorials, articles, and tips.","meta_title":null,"meta_description":null,"featureImageSharp":{"base":"photo-1581276879432-15e50529f34b.jpg","publicURL":"/static/7140ea32e1157ba61402d5d67ab846d4/photo-1581276879432-15e50529f34b.jpg","imageMeta":{"width":2000,"height":1333},"childImageSharp":{"fluid":{"base64":"data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAANABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAIDBf/EABUBAQEAAAAAAAAAAAAAAAAAAAAB/9oADAMBAAIQAxAAAAHJai1MBP/EABcQAAMBAAAAAAAAAAAAAAAAAAABEBH/2gAIAQEAAQUCuDU//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPwE//8QAFREBAQAAAAAAAAAAAAAAAAAAEBH/2gAIAQIBAT8Bh//EABQQAQAAAAAAAAAAAAAAAAAAACD/2gAIAQEABj8CX//EABgQAQEBAQEAAAAAAAAAAAAAAAABESFR/9oACAEBAAE/IYy+rHKDH//aAAwDAQACAAMAAAAQC9//xAAVEQEBAAAAAAAAAAAAAAAAAAAQEf/aAAgBAwEBPxCn/8QAFREBAQAAAAAAAAAAAAAAAAAAARD/2gAIAQIBAT8QUT//xAAaEAADAQADAAAAAAAAAAAAAAAAAREhQWFx/9oACAEBAAE/EMY0neijzwMrrVEm7auUQPNGlP/Z","aspectRatio":1.5028901734104045,"src":"/static/7140ea32e1157ba61402d5d67ab846d4/d5c54/photo-1581276879432-15e50529f34b.jpg","srcSet":"/static/7140ea32e1157ba61402d5d67ab846d4/65d8c/photo-1581276879432-15e50529f34b.jpg 260w,\n/static/7140ea32e1157ba61402d5d67ab846d4/c5f21/photo-1581276879432-15e50529f34b.jpg 520w,\n/static/7140ea32e1157ba61402d5d67ab846d4/d5c54/photo-1581276879432-15e50529f34b.jpg 1040w,\n/static/7140ea32e1157ba61402d5d67ab846d4/81a53/photo-1581276879432-15e50529f34b.jpg 1560w,\n/static/7140ea32e1157ba61402d5d67ab846d4/4e5f3/photo-1581276879432-15e50529f34b.jpg 2000w","srcWebp":"/static/7140ea32e1157ba61402d5d67ab846d4/e4875/photo-1581276879432-15e50529f34b.webp","srcSetWebp":"/static/7140ea32e1157ba61402d5d67ab846d4/dc8f3/photo-1581276879432-15e50529f34b.webp 260w,\n/static/7140ea32e1157ba61402d5d67ab846d4/2db4b/photo-1581276879432-15e50529f34b.webp 520w,\n/static/7140ea32e1157ba61402d5d67ab846d4/e4875/photo-1581276879432-15e50529f34b.webp 1040w,\n/static/7140ea32e1157ba61402d5d67ab846d4/f5845/photo-1581276879432-15e50529f34b.webp 1560w,\n/static/7140ea32e1157ba61402d5d67ab846d4/49d6b/photo-1581276879432-15e50529f34b.webp 2000w","sizes":"(max-width: 1040px) 100vw, 1040px"}}}},"tags":[{"slug":"react","url":"https://backend.shahednasser.com/tag/react/","name":"React","visibility":"public","feature_image":"https://images.unsplash.com/photo-1581276879432-15e50529f34b?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=MnwxMTc3M3wwfDF8c2VhcmNofDN8fHJlYWN0fGVufDB8fHx8MTYyMjYzMzI0MA&ixlib=rb-1.2.1&q=80&w=2000","description":"Learn more about React through tutorials, articles, and tips.","meta_title":null,"meta_description":null,"featureImageSharp":null},{"slug":"js","url":"https://backend.shahednasser.com/tag/js/","name":"Javascript","visibility":"public","feature_image":"https://backend.shahednasser.com/content/images/2022/01/photo-1592609931095-54a2168ae893-2.jpeg","description":"Learn more about Javascript through tutorials, articles, and tips.","meta_title":null,"meta_description":"Learn more about Javascript through tutorials, articles and tips.","featureImageSharp":null}],"plaintext":"Perhaps one of the most annoying tasks in React is creating forms and validating\nthem, especially if you're doing it without using any libraries. You'll have to\nmanage the states, values, and validation of all inputs.\n\nFormik [https://formik.org] is a React and React Native library that helps you\ncreate forms in React \"without the tears\". You can pair Formik with validation\nlibraries like Yup [https://github.com/jquense/yup] to make the process even\nsimpler.\n\nIn this tutorial, you'll learn how creating and validating forms can be simpler\nin React using Formik and Yup. You'll create a simple form with different types\nof fields and see the different ways you can validate that form.\n\nYou can find the code for this tutorial in this GitHub repository\n[https://github.com/shahednasser/react-forms-tutorial].\n\nProject Setup\nIn this section, you'll set up your website using Create React App\n[https://create-react-app.dev] (CRA) and install some dependencies for the sake\nof the tutorial. If you already have a website set up you can skip this part.\n\nIn your terminal, run the following command to create a new React website with\nCRA:\n\nnpx create-react-app react-forms\n\nI'm calling the website react-forms but you can change it to whatever you want.\n\nOnce the installation is done, change to the newly created directory:\n\ncd react-forms\n\nThen, install Tailwind CSS [https://tailwindcss.com] to add some styling to your\nwebsite:\n\nnpm install -D tailwindcss postcss autoprefixer\n\nTo set up Tailwind CSS create the file tailwind.config.js with the following\ncontent:\n\nmodule.exports = {\n  content: [\n    \"./src/**/*.{js,jsx,ts,tsx}\",\n  ],\n  theme: {\n    extend: {},\n  },\n  plugins: [],\n}\n\nAnd replace the content of src/index.css with the following:\n\n@tailwind base;\n@tailwind components;\n@tailwind utilities;\n\nCreate the Form with Formik\nYou'll now use Formik to create a form. First, install Formik:\n\nnpm i formik\n\nReplace the content of src/App.js with the following:\n\nimport { useFormik } from 'formik';\n\nfunction App() {\n    const professions = ['Developer', 'Designer', 'Other'];\n    //TODO create formik instance\n    \n    return (\n    \t<div className=\"bg-blue-300 min-w-screen min-h-screen overflow-x-hidden\">\n        </div>\n    );\n}\n\nexport default App;\n\nAll you did here is create the component App which does nothing special at the\nmoment.\n\nNotice how you import the useFormik hook at the beginning of the file. You'll\nuse this hook to create a Formik instance with all the states and helpers you'll\nneed.\n\nThe useFormik hook accepts as a parameter an object of configurations\n[https://formik.org/docs/api/formik#props-1]. These configurations can be used\nto modify and shape your form as you need.\n\nIn this tutorial, you'll use the pass the following properties in the object:\n\n 1. initialValues: includes the form fields and their initial values.\n 2. validationSchema: A Yup schema to validate the fields. You'll use this in\n    the next section.\n 3. onSubmit: a function to execute when the form is submitted.\n\nReplace the TODO in the App component with the following:\n\nconst formik = useFormik({\n    initialValues: {\n      name: '',\n      email: '',\n      profession: professions[0],\n      age: '',\n    },\n    onSubmit: function (values) {\n      alert(`You are registered! Name: ${values.name}. Email: ${values.email}. Profession: ${values.profession}. \n        Age: ${values.age}`);\n    }\n  })\n\nAs you can see, you set the value of the property initialValues to an object.\nThis object's keys are the names of the fields in the form. Their values are the\ninitial value.\n\nIn the onSubmit function, you receive the values object as a parameter. Here you\ncan access the values and use them to save them in the database or send them to\na server. For the sake of this tutorial, you just print them out in an alert.\n\nNote that the onSubmit function is only executed once the form is validated. So,\nyou don't need to perform any validation inside this function.\n\nNow, you can use the formik variable to create a form, link its fields to the\nfields you defined in useFormik, link the validation, and link the submit\nhandler.\n\nformik includes the following properties among others\n[https://formik.org/docs/api/formik#props-1]:\n\n 1. handleSubmit: the submit function that should be called when the form is\n    submitted. This is usually assigned to the onSubmit event handler of form \n    elements.\n 2. errors: An object that has the field names as properties and the value of\n    each is the error message resulted from validating that field if there are\n    any errors.\n 3. touched: An object that has the field names as properties and the value is a\n    boolean indicating whether the user has interacted with the field or not.\n 4. values: An object that has the field names as properties and the value of\n    each is the current value of that field. It's usually used to set the value \n    property of input elements.\n 5. handleChange: A function that should be used as the handler of the change\n    event of input elements. It's passed as the value of the onChange prop of\n    elements.\n 6. handleBlur: A function that should be used as the handler of the blur event\n    of input elements. It's passed as the value of the onBlur prop of elements.\n\nReplace the return statement in App with the following:\n\nreturn (\n    <div className=\"bg-blue-300 min-w-screen min-h-screen overflow-x-hidden\">\n      <form onSubmit={formik.handleSubmit} className=\"max-w-lg mx-auto bg-white rounded shadow-lg mt-7 p-3\">\n      <h1 className='text-3xl mb-3 text-center'>Register</h1>\n        <div className='mb-4'>\n          <label for=\"name\">Full Name</label>\n          <input type=\"text\" name=\"name\" id=\"name\" \n            className={`block w-full rounded border py-1 px-2 ${formik.touched.name && formik.errors.name ? 'border-red-400' : 'border-gray-300'}`}\n            onChange={formik.handleChange} onBlur={formik.handleBlur} value={formik.values.name} />\n          {formik.touched.name && formik.errors.name && (\n            <span className='text-red-400'>{formik.errors.name}</span>\n          )}\n        </div>\n        <div className='mb-4'>\n          <label for=\"email\">Email</label>\n          <input type=\"email\" name=\"email\" id=\"email\"\n            className={`block w-full rounded border py-1 px-2 ${formik.touched.email && formik.errors.email ? 'border-red-400' : 'border-gray-300'}`}\n            onChange={formik.handleChange} onBlur={formik.handleBlur} value={formik.values.email} />\n          {formik.touched.email && formik.errors.email && (\n            <span className='text-red-400'>{formik.errors.email}</span>\n          )}\n        </div>\n        <div className='mb-4'>\n          <label for=\"profession\">Profession</label>\n          <select name=\"profession\" id=\"profession\"\n            className={`block w-full rounded border py-1 px-2 ${formik.touched.profession && formik.errors.profession ? 'border-red-400' : 'border-gray-300'}`}\n            onChange={formik.handleChange} onBlur={formik.handleBlur} value={formik.values.profession} >\n            {professions.map((profession, index) => (\n              <option value={profession} key={index}>{profession}</option>\n            ))}\n          </select>\n          {formik.touched.profession && formik.errors.profession && (\n            <span className='text-red-400'>{formik.errors.profession}</span>\n          )}\n        </div>\n        <div className='mb-4'>\n          <label for=\"age\">Age</label>\n          <input type=\"number\" name=\"age\" id=\"age\"\n            className={`block w-full rounded border py-1 px-2 ${formik.touched.age && formik.errors.age ? 'border-red-400' : 'border-gray-300'}`}\n            onChange={formik.handleChange} onBlur={formik.handleBlur} value={formik.values.age} />\n          {formik.touched.age && formik.errors.age && (\n            <span className='text-red-400'>{formik.errors.age}</span>\n          )}\n        </div>\n        <div className='text-center'>\n          <button className='bg-blue-500 rounded p-3 text-white' type='submit'>Submit</button>\n        </div>\n      </form>\n    </div>\n  );\n\nNotice how you used all the properties in the formik variable mentioned earlier.\n\nTest it Out\nThe form is now created and ready to be used, even if there's no validation yet.\n\nTo test it out, run the server using the following command:\n\nnpm start\n\nYou can then open the website at localhost:3000 (default port). If you open the\nwebsite, you'll see the form with 4 fields.\n\nYou can try and fill out the form. As currently there's no validation, you can\nfill out (or not) values as you want and click Submit. An alert will show with\nthe values you entered.\n\nAdd Validation with Yup\nIn this section, you'll add validation to the form using Yup.\n\nFirst, you need to install Yup. Run the following in your terminal:\n\nnpm i yup\n\nYup has a lot of methods and validation rules\n[https://github.com/jquense/yup#table-of-contents] you can use. The way it works\nwith Formik is you need to create a validation schema and pass it to useFormik \nas a value to the property validationSchema.\n\nYup validation schemas are created using Yup.object method which takes as a\nparameter an object. This object has the field names as properties and their\nvalues are validation rules from the Yup library.\n\nImport Yup at the beginning of src/App.js:\n\nimport * as Yup from 'yup';\n\nThen, add the property validationSchema to the object passed to useFormik with\nthe following value:\n\nconst formik = useFormik({\n    ...,\n    validationSchema: Yup.object({\n      name: Yup.string()\n              .label('Full Name')\n              .required(),\n      email: Yup.string()\n              .email()\n              .required(),\n      profession: Yup.string()\n                  .oneOf(professions, 'The profession you chose does not exist'),\n      age: Yup.number()\n            .min(15, 'You need to be older than 15 to register')\n            .required()\n    })\n  })\n\nYou add the following validation rules:\n\n 1. name: Should be a string and is required. You also use the label method to\n    ensure that when the error message is shown it refers to the field as \"Full\n    Name\". By default, the fields are referred to by the field name, which in\n    this case is name.\n 2. email: Should be a string, an email, and required.\n 3. profession: Should be a string and one of the values in the professions \n    array. You also pass a message as a second parameter to oneOf which will be\n    the message that shows in case there's an error. It's also required.\n 4. age: Should be a number and at least 15. If the age is less than 15, the\n    message \"You need to be older than 15 to register\" will show. It's also\n    required.\n\nTest it Out\nLet's test it out. Run the server again if it's not running and open the\nwebsite. If you enter values now that don't comply with the rules you set in the\nvalidation schema, an error will show in red and you won't be able to submit the\nform before resolving the errors.\n\nIf you all values are valid, then the form will be submitted and an alert will\nshow.\n\nCustom Validation Rules\nAlthough Yup has helpful validation rules that you can use with most common\ncases, a lot of times you might need a custom validation rule. You can use the \ntest\n[https://github.com/jquense/yup#schematestname-string-message-string--function--any-test-function-schema] \nfunction to add a custom rule.\n\nIn this section, you'll add a rule to make sure that the name field has both\nfirst and last name.\n\nChange the name property inside the validationSchema to the following:\n\nconst formik = useFormik({\n    ...,\n    validationSchema: Yup.object({\n      name: Yup.string()\n              .label('Full Name')\n              .required()\n              .test('is-full-name', 'Please enter both your first and last name', function (value) {\n                const nameArr = value.split(\" \");\n                return nameArr.length >= 2;\n              }),\n      ...\n    })\n  })\n\nThe first parameter is the name of the custom rule. The second parameter is the\nmessage to show in case the field is invalid. \n\nThe third parameter is the function that determines whether the field is valid\nor not. It should return a boolean value. If the value is true, then the field\nis valid. Otherwise, it's invalid.\n\nYou validate the name field to contain both first and last names by just\nsplitting it  on the space delimiter which will return an array. You then check\nthe array length. If it's at least 2, then the field is valid. Otherwise it's\ninvalid.\n\nTest it Out\nRun the server again now and go to the website. If you enter one word in the\nFull Name field you'll see an error.\n\nYou'll need to enter at least two words for the field to be valid.\n\nConclusion\nIn this tutorial you learned how to use Formik and Yup in React. You can use\nthese two libraries to create forms, validate them, and handle their submission.\nUsing these two libraries makes creating forms in React easier and less\nstressful.","html":"<p>Perhaps one of the most annoying tasks in React is creating forms and validating them, especially if you're doing it without using any libraries. You'll have to manage the states, values, and validation of all inputs.</p><p><a href=\"https://formik.org\">Formik</a> is a React and React Native library that helps you create forms in React \"without the tears\". You can pair Formik with validation libraries like <a href=\"https://github.com/jquense/yup\">Yup</a> to make the process even simpler.</p><p>In this tutorial, you'll learn how creating and validating forms can be simpler in React using Formik and Yup. You'll create a simple form with different types of fields and see the different ways you can validate that form.</p><p>You can find the code for this tutorial in <a href=\"https://github.com/shahednasser/react-forms-tutorial\">this GitHub repository</a>.</p><h2 id=\"project-setup\">Project Setup</h2><p>In this section, you'll set up your website using <a href=\"https://create-react-app.dev\">Create React App</a> (CRA) and install some dependencies for the sake of the tutorial. If you already have a website set up you can skip this part.</p><p>In your terminal, run the following command to create a new React website with CRA:</p><pre><code class=\"language-bash\">npx create-react-app react-forms</code></pre><p>I'm calling the website <code>react-forms</code> but you can change it to whatever you want.</p><p>Once the installation is done, change to the newly created directory:</p><pre><code class=\"language-bash\">cd react-forms</code></pre><p>Then, install <a href=\"https://tailwindcss.com\">Tailwind CSS</a> to add some styling to your website:</p><pre><code class=\"language-bash\">npm install -D tailwindcss postcss autoprefixer</code></pre><p>To set up Tailwind CSS create the file <code>tailwind.config.js</code> with the following content:</p><pre><code class=\"language-bash\">module.exports = {\n  content: [\n    \"./src/**/*.{js,jsx,ts,tsx}\",\n  ],\n  theme: {\n    extend: {},\n  },\n  plugins: [],\n}</code></pre><p>And replace the content of <code>src/index.css</code> with the following:</p><pre><code class=\"language-bash\">@tailwind base;\n@tailwind components;\n@tailwind utilities;</code></pre><h2 id=\"create-the-form-with-formik\">Create the Form with Formik</h2><p>You'll now use Formik to create a form. First, install Formik:</p><pre><code class=\"language-bash\">npm i formik</code></pre><p>Replace the content of <code>src/App.js</code> with the following:</p><pre><code class=\"language-js\">import { useFormik } from 'formik';\n\nfunction App() {\n    const professions = ['Developer', 'Designer', 'Other'];\n    //TODO create formik instance\n    \n    return (\n    \t&lt;div className=\"bg-blue-300 min-w-screen min-h-screen overflow-x-hidden\"&gt;\n        &lt;/div&gt;\n    );\n}\n\nexport default App;</code></pre><p>All you did here is create the component App which does nothing special at the moment.</p><p>Notice how you import the <code>useFormik</code> hook at the beginning of the file. You'll use this hook to create a Formik instance with all the states and helpers you'll need.</p><p>The <code>useFormik</code> hook accepts as a parameter an object of <a href=\"https://formik.org/docs/api/formik#props-1\">configurations</a>. These configurations can be used to modify and shape your form as you need.</p><p>In this tutorial, you'll use the pass the following properties in the object:</p><ol><li><code>initialValues</code>: includes the form fields and their initial values.</li><li><code>validationSchema</code>: A Yup schema to validate the fields. You'll use this in the next section.</li><li><code>onSubmit</code>: a function to execute when the form is submitted.</li></ol><p>Replace the <code>TODO</code> in the <code>App</code> component with the following:</p><pre><code class=\"language-js\">const formik = useFormik({\n    initialValues: {\n      name: '',\n      email: '',\n      profession: professions[0],\n      age: '',\n    },\n    onSubmit: function (values) {\n      alert(`You are registered! Name: ${values.name}. Email: ${values.email}. Profession: ${values.profession}. \n        Age: ${values.age}`);\n    }\n  })</code></pre><p>As you can see, you set the value of the property <code>initialValues</code> to an object. This object's keys are the names of the fields in the form. Their values are the initial value.</p><p>In the <code>onSubmit</code> function, you receive the <code>values</code> object as a parameter. Here you can access the values and use them to save them in the database or send them to a server. For the sake of this tutorial, you just print them out in an alert.</p><p>Note that the <code>onSubmit</code> function is only executed once the form is validated. So, you don't need to perform any validation inside this function.</p><p>Now, you can use the <code>formik</code> variable to create a form, link its fields to the fields you defined in <code>useFormik</code>, link the validation, and link the submit handler.</p><p><code>formik</code> includes the following properties among <a href=\"https://formik.org/docs/api/formik#props-1\">others</a>:</p><ol><li><code>handleSubmit</code>: the submit function that should be called when the form is submitted. This is usually assigned to the <code>onSubmit</code> event handler of <code>form</code> elements.</li><li><code>errors</code>: An object that has the field names as properties and the value of each is the error message resulted from validating that field if there are any errors.</li><li><code>touched</code>: An object that has the field names as properties and the value is a boolean indicating whether the user has interacted with the field or not.</li><li><code>values</code>: An object that has the field names as properties and the value of each is the current value of that field. It's usually used to set the <code>value</code> property of input elements.</li><li><code>handleChange</code>: A function that should be used as the handler of the change event of input elements. It's passed as the value of the <code>onChange</code> prop of elements.</li><li><code>handleBlur</code>: A function that should be used as the handler of the blur event of input elements. It's passed as the value of the <code>onBlur</code> prop of elements.</li></ol><p>Replace the return statement in <code>App</code> with the following:</p><pre><code class=\"language-js\">return (\n    &lt;div className=\"bg-blue-300 min-w-screen min-h-screen overflow-x-hidden\"&gt;\n      &lt;form onSubmit={formik.handleSubmit} className=\"max-w-lg mx-auto bg-white rounded shadow-lg mt-7 p-3\"&gt;\n      &lt;h1 className='text-3xl mb-3 text-center'&gt;Register&lt;/h1&gt;\n        &lt;div className='mb-4'&gt;\n          &lt;label for=\"name\"&gt;Full Name&lt;/label&gt;\n          &lt;input type=\"text\" name=\"name\" id=\"name\" \n            className={`block w-full rounded border py-1 px-2 ${formik.touched.name &amp;&amp; formik.errors.name ? 'border-red-400' : 'border-gray-300'}`}\n            onChange={formik.handleChange} onBlur={formik.handleBlur} value={formik.values.name} /&gt;\n          {formik.touched.name &amp;&amp; formik.errors.name &amp;&amp; (\n            &lt;span className='text-red-400'&gt;{formik.errors.name}&lt;/span&gt;\n          )}\n        &lt;/div&gt;\n        &lt;div className='mb-4'&gt;\n          &lt;label for=\"email\"&gt;Email&lt;/label&gt;\n          &lt;input type=\"email\" name=\"email\" id=\"email\"\n            className={`block w-full rounded border py-1 px-2 ${formik.touched.email &amp;&amp; formik.errors.email ? 'border-red-400' : 'border-gray-300'}`}\n            onChange={formik.handleChange} onBlur={formik.handleBlur} value={formik.values.email} /&gt;\n          {formik.touched.email &amp;&amp; formik.errors.email &amp;&amp; (\n            &lt;span className='text-red-400'&gt;{formik.errors.email}&lt;/span&gt;\n          )}\n        &lt;/div&gt;\n        &lt;div className='mb-4'&gt;\n          &lt;label for=\"profession\"&gt;Profession&lt;/label&gt;\n          &lt;select name=\"profession\" id=\"profession\"\n            className={`block w-full rounded border py-1 px-2 ${formik.touched.profession &amp;&amp; formik.errors.profession ? 'border-red-400' : 'border-gray-300'}`}\n            onChange={formik.handleChange} onBlur={formik.handleBlur} value={formik.values.profession} &gt;\n            {professions.map((profession, index) =&gt; (\n              &lt;option value={profession} key={index}&gt;{profession}&lt;/option&gt;\n            ))}\n          &lt;/select&gt;\n          {formik.touched.profession &amp;&amp; formik.errors.profession &amp;&amp; (\n            &lt;span className='text-red-400'&gt;{formik.errors.profession}&lt;/span&gt;\n          )}\n        &lt;/div&gt;\n        &lt;div className='mb-4'&gt;\n          &lt;label for=\"age\"&gt;Age&lt;/label&gt;\n          &lt;input type=\"number\" name=\"age\" id=\"age\"\n            className={`block w-full rounded border py-1 px-2 ${formik.touched.age &amp;&amp; formik.errors.age ? 'border-red-400' : 'border-gray-300'}`}\n            onChange={formik.handleChange} onBlur={formik.handleBlur} value={formik.values.age} /&gt;\n          {formik.touched.age &amp;&amp; formik.errors.age &amp;&amp; (\n            &lt;span className='text-red-400'&gt;{formik.errors.age}&lt;/span&gt;\n          )}\n        &lt;/div&gt;\n        &lt;div className='text-center'&gt;\n          &lt;button className='bg-blue-500 rounded p-3 text-white' type='submit'&gt;Submit&lt;/button&gt;\n        &lt;/div&gt;\n      &lt;/form&gt;\n    &lt;/div&gt;\n  );</code></pre><p>Notice how you used all the properties in the <code>formik</code> variable mentioned earlier.</p><h3 id=\"test-it-out\">Test it Out</h3><p>The form is now created and ready to be used, even if there's no validation yet.</p><p>To test it out, run the server using the following command:</p><pre><code class=\"language-bash\">npm start</code></pre><p>You can then open the website at <code>localhost:3000</code> (default port). If you open the website, you'll see the form with 4 fields.</p><figure class=\"kg-card kg-image-card\"><img src=\"https://backend.shahednasser.com/content/images/2022/03/Screen-Shot-2022-03-19-at-2.49.28-PM-1.png\" class=\"kg-image\" alt loading=\"lazy\" width=\"1084\" height=\"900\"></figure><p>You can try and fill out the form. As currently there's no validation, you can fill out (or not) values as you want and click Submit. An alert will show with the values you entered.</p><figure class=\"kg-card kg-image-card\"><img src=\"https://backend.shahednasser.com/content/images/2022/03/Screen-Shot-2022-03-19-at-2.50.35-PM-1.png\" class=\"kg-image\" alt loading=\"lazy\" width=\"1010\" height=\"410\"></figure><h2 id=\"add-validation-with-yup\">Add Validation with Yup</h2><p>In this section, you'll add validation to the form using Yup.</p><p>First, you need to install Yup. Run the following in your terminal:</p><pre><code class=\"language-bash\">npm i yup</code></pre><p>Yup has a lot of <a href=\"https://github.com/jquense/yup#table-of-contents\">methods and validation rules</a> you can use. The way it works with Formik is you need to create a validation schema and pass it to <code>useFormik</code> as a value to the property <code>validationSchema</code>.</p><p>Yup validation schemas are created using <code>Yup.object</code> method which takes as a parameter an object. This object has the field names as properties and their values are validation rules from the Yup library.</p><p>Import Yup at the beginning of <code>src/App.js</code>:</p><pre><code class=\"language-js\">import * as Yup from 'yup';</code></pre><p>Then, add the property <code>validationSchema</code> to the object passed to <code>useFormik</code> with the following value:</p><pre><code class=\"language-js\">const formik = useFormik({\n    ...,\n    validationSchema: Yup.object({\n      name: Yup.string()\n              .label('Full Name')\n              .required(),\n      email: Yup.string()\n              .email()\n              .required(),\n      profession: Yup.string()\n                  .oneOf(professions, 'The profession you chose does not exist'),\n      age: Yup.number()\n            .min(15, 'You need to be older than 15 to register')\n            .required()\n    })\n  })</code></pre><p>You add the following validation rules:</p><ol><li><code>name</code>: Should be a string and is required. You also use the <code>label</code> method to ensure that when the error message is shown it refers to the field as \"Full Name\". By default, the fields are referred to by the field name, which in this case is <code>name</code>.</li><li><code>email</code>: Should be a string, an email, and required.</li><li><code>profession</code>: Should be a string and one of the values in the <code>professions</code> array. You also pass a message as a second parameter to <code>oneOf</code> which will be the message that shows in case there's an error. It's also required.</li><li><code>age</code>: Should be a number and at least 15. If the age is less than 15, the message \"You need to be older than 15 to register\" will show. It's also required.</li></ol><h3 id=\"test-it-out-1\">Test it Out</h3><p>Let's test it out. Run the server again if it's not running and open the website. If you enter values now that don't comply with the rules you set in the validation schema, an error will show in red and you won't be able to submit the form before resolving the errors.</p><figure class=\"kg-card kg-image-card\"><img src=\"https://backend.shahednasser.com/content/images/2022/03/Screen-Shot-2022-03-19-at-2.55.58-PM-1.png\" class=\"kg-image\" alt loading=\"lazy\" width=\"1102\" height=\"938\"></figure><p>If you all values are valid, then the form will be submitted and an alert will show.</p><h3 id=\"custom-validation-rules\">Custom Validation Rules</h3><p>Although Yup has helpful validation rules that you can use with most common cases, a lot of times you might need a custom validation rule. You can use the <a href=\"https://github.com/jquense/yup#schematestname-string-message-string--function--any-test-function-schema\">test</a> function to add a custom rule.</p><p>In this section, you'll add a rule to make sure that the <code>name</code> field has both first and last name.</p><p>Change the <code>name</code> property inside the <code>validationSchema</code> to the following:</p><pre><code class=\"language-js\">const formik = useFormik({\n    ...,\n    validationSchema: Yup.object({\n      name: Yup.string()\n              .label('Full Name')\n              .required()\n              .test('is-full-name', 'Please enter both your first and last name', function (value) {\n                const nameArr = value.split(\" \");\n                return nameArr.length &gt;= 2;\n              }),\n      ...\n    })\n  })</code></pre><p>The first parameter is the name of the custom rule. The second parameter is the message to show in case the field is invalid. </p><p>The third parameter is the function that determines whether the field is valid or not. It should return a boolean value. If the value is true, then the field is valid. Otherwise, it's invalid.</p><p>You validate the name field to contain both first and last names by just splitting it  on the space delimiter which will return an array. You then check the array length. If it's at least 2, then the field is valid. Otherwise it's invalid.</p><h3 id=\"test-it-out-2\">Test it Out</h3><p>Run the server again now and go to the website. If you enter one word in the Full Name field you'll see an error.</p><figure class=\"kg-card kg-image-card\"><img src=\"https://backend.shahednasser.com/content/images/2022/03/us9mldxrs5dvf174r4w9.png.jpeg\" class=\"kg-image\" alt loading=\"lazy\" width=\"880\" height=\"192\"></figure><p>You'll need to enter at least two words for the field to be valid.</p><h2 id=\"conclusion\">Conclusion</h2><p>In this tutorial you learned how to use Formik and Yup in React. You can use these two libraries to create forms, validate them, and handle their submission. Using these two libraries makes creating forms in React easier and less stressful.</p>","url":"https://backend.shahednasser.com/how-to-create-and-validate-forms-in-react-using-formik-and-yup/","canonical_url":null,"uuid":"a59816b7-049f-45fe-9497-bb708c803a15","codeinjection_foot":null,"codeinjection_head":null,"codeinjection_styles":null,"comment_id":"6235d3ec1594e705e60e186f","reading_time":8,"send_email_when_published":null,"email_subject":null,"childHtmlRehype":{"html":"<p>Perhaps one of the most annoying tasks in React is creating forms and validating them, especially if you're doing it without using any libraries. You'll have to manage the states, values, and validation of all inputs.</p><p><a href=\"https://formik.org\">Formik</a> is a React and React Native library that helps you create forms in React \"without the tears\". You can pair Formik with validation libraries like <a href=\"https://github.com/jquense/yup\">Yup</a> to make the process even simpler.</p><p>In this tutorial, you'll learn how creating and validating forms can be simpler in React using Formik and Yup. You'll create a simple form with different types of fields and see the different ways you can validate that form.</p><p>You can find the code for this tutorial in <a href=\"https://github.com/shahednasser/react-forms-tutorial\">this GitHub repository</a>.</p><h2 id=\"project-setup\">Project Setup</h2><p>In this section, you'll set up your website using <a href=\"https://create-react-app.dev\">Create React App</a> (CRA) and install some dependencies for the sake of the tutorial. If you already have a website set up you can skip this part.</p><p>In your terminal, run the following command to create a new React website with CRA:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">npx create-react-app react-forms</code></pre></div><p>I'm calling the website <code class=\"language-text\">react-forms</code> but you can change it to whatever you want.</p><p>Once the installation is done, change to the newly created directory:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\"><span class=\"token builtin class-name\">cd</span> react-forms</code></pre></div><p>Then, install <a href=\"https://tailwindcss.com\">Tailwind CSS</a> to add some styling to your website:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\"><span class=\"token function\">npm</span> <span class=\"token function\">install</span> -D tailwindcss postcss autoprefixer</code></pre></div><p>To set up Tailwind CSS create the file <code class=\"language-text\">tailwind.config.js</code> with the following content:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">module.exports <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span>\n  content: <span class=\"token punctuation\">[</span>\n    <span class=\"token string\">\"./src/**/*.{js,jsx,ts,tsx}\"</span>,\n  <span class=\"token punctuation\">]</span>,\n  theme: <span class=\"token punctuation\">{</span>\n    extend: <span class=\"token punctuation\">{</span><span class=\"token punctuation\">}</span>,\n  <span class=\"token punctuation\">}</span>,\n  plugins: <span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span>,\n<span class=\"token punctuation\">}</span></code></pre></div><p>And replace the content of <code class=\"language-text\">src/index.css</code> with the following:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">@tailwind base<span class=\"token punctuation\">;</span>\n@tailwind components<span class=\"token punctuation\">;</span>\n@tailwind utilities<span class=\"token punctuation\">;</span></code></pre></div><h2 id=\"create-the-form-with-formik\">Create the Form with Formik</h2><p>You'll now use Formik to create a form. First, install Formik:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\"><span class=\"token function\">npm</span> i formik</code></pre></div><p>Replace the content of <code class=\"language-text\">src/App.js</code> with the following:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span> useFormik <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'formik'</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token keyword\">function</span> <span class=\"token function\">App</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">const</span> professions <span class=\"token operator\">=</span> <span class=\"token punctuation\">[</span><span class=\"token string\">'Developer'</span><span class=\"token punctuation\">,</span> <span class=\"token string\">'Designer'</span><span class=\"token punctuation\">,</span> <span class=\"token string\">'Other'</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">;</span>\n    <span class=\"token comment\">//TODO create formik instance</span>\n    \n    <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span>\n    \t<span class=\"token operator\">&#x3C;</span>div className<span class=\"token operator\">=</span><span class=\"token string\">\"bg-blue-300 min-w-screen min-h-screen overflow-x-hidden\"</span><span class=\"token operator\">></span>\n        <span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>div<span class=\"token operator\">></span>\n    <span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">export</span> <span class=\"token keyword\">default</span> App<span class=\"token punctuation\">;</span></code></pre></div><p>All you did here is create the component App which does nothing special at the moment.</p><p>Notice how you import the <code class=\"language-text\">useFormik</code> hook at the beginning of the file. You'll use this hook to create a Formik instance with all the states and helpers you'll need.</p><p>The <code class=\"language-text\">useFormik</code> hook accepts as a parameter an object of <a href=\"https://formik.org/docs/api/formik#props-1\">configurations</a>. These configurations can be used to modify and shape your form as you need.</p><p>In this tutorial, you'll use the pass the following properties in the object:</p><ol><li><code class=\"language-text\">initialValues</code>: includes the form fields and their initial values.</li><li><code class=\"language-text\">validationSchema</code>: A Yup schema to validate the fields. You'll use this in the next section.</li><li><code class=\"language-text\">onSubmit</code>: a function to execute when the form is submitted.</li></ol><p>Replace the <code class=\"language-text\">TODO</code> in the <code class=\"language-text\">App</code> component with the following:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">const</span> formik <span class=\"token operator\">=</span> <span class=\"token function\">useFormik</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>\n    <span class=\"token literal-property property\">initialValues</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span>\n      <span class=\"token literal-property property\">name</span><span class=\"token operator\">:</span> <span class=\"token string\">''</span><span class=\"token punctuation\">,</span>\n      <span class=\"token literal-property property\">email</span><span class=\"token operator\">:</span> <span class=\"token string\">''</span><span class=\"token punctuation\">,</span>\n      <span class=\"token literal-property property\">profession</span><span class=\"token operator\">:</span> professions<span class=\"token punctuation\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span>\n      <span class=\"token literal-property property\">age</span><span class=\"token operator\">:</span> <span class=\"token string\">''</span><span class=\"token punctuation\">,</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n    <span class=\"token function-variable function\">onSubmit</span><span class=\"token operator\">:</span> <span class=\"token keyword\">function</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">values</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n      <span class=\"token function\">alert</span><span class=\"token punctuation\">(</span><span class=\"token template-string\"><span class=\"token template-punctuation string\">`</span><span class=\"token string\">You are registered! Name: </span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${</span>values<span class=\"token punctuation\">.</span>name<span class=\"token interpolation-punctuation punctuation\">}</span></span><span class=\"token string\">. Email: </span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${</span>values<span class=\"token punctuation\">.</span>email<span class=\"token interpolation-punctuation punctuation\">}</span></span><span class=\"token string\">. Profession: </span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${</span>values<span class=\"token punctuation\">.</span>profession<span class=\"token interpolation-punctuation punctuation\">}</span></span><span class=\"token string\">. \n        Age: </span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${</span>values<span class=\"token punctuation\">.</span>age<span class=\"token interpolation-punctuation punctuation\">}</span></span><span class=\"token template-punctuation string\">`</span></span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span></code></pre></div><p>As you can see, you set the value of the property <code class=\"language-text\">initialValues</code> to an object. This object's keys are the names of the fields in the form. Their values are the initial value.</p><p>In the <code class=\"language-text\">onSubmit</code> function, you receive the <code class=\"language-text\">values</code> object as a parameter. Here you can access the values and use them to save them in the database or send them to a server. For the sake of this tutorial, you just print them out in an alert.</p><p>Note that the <code class=\"language-text\">onSubmit</code> function is only executed once the form is validated. So, you don't need to perform any validation inside this function.</p><p>Now, you can use the <code class=\"language-text\">formik</code> variable to create a form, link its fields to the fields you defined in <code class=\"language-text\">useFormik</code>, link the validation, and link the submit handler.</p><p><code class=\"language-text\">formik</code> includes the following properties among <a href=\"https://formik.org/docs/api/formik#props-1\">others</a>:</p><ol><li><code class=\"language-text\">handleSubmit</code>: the submit function that should be called when the form is submitted. This is usually assigned to the <code class=\"language-text\">onSubmit</code> event handler of <code class=\"language-text\">form</code> elements.</li><li><code class=\"language-text\">errors</code>: An object that has the field names as properties and the value of each is the error message resulted from validating that field if there are any errors.</li><li><code class=\"language-text\">touched</code>: An object that has the field names as properties and the value is a boolean indicating whether the user has interacted with the field or not.</li><li><code class=\"language-text\">values</code>: An object that has the field names as properties and the value of each is the current value of that field. It's usually used to set the <code class=\"language-text\">value</code> property of input elements.</li><li><code class=\"language-text\">handleChange</code>: A function that should be used as the handler of the change event of input elements. It's passed as the value of the <code class=\"language-text\">onChange</code> prop of elements.</li><li><code class=\"language-text\">handleBlur</code>: A function that should be used as the handler of the blur event of input elements. It's passed as the value of the <code class=\"language-text\">onBlur</code> prop of elements.</li></ol><p>Replace the return statement in <code class=\"language-text\">App</code> with the following:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span>\n    <span class=\"token operator\">&#x3C;</span>div className<span class=\"token operator\">=</span><span class=\"token string\">\"bg-blue-300 min-w-screen min-h-screen overflow-x-hidden\"</span><span class=\"token operator\">></span>\n      <span class=\"token operator\">&#x3C;</span>form onSubmit<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span>formik<span class=\"token punctuation\">.</span>handleSubmit<span class=\"token punctuation\">}</span> className<span class=\"token operator\">=</span><span class=\"token string\">\"max-w-lg mx-auto bg-white rounded shadow-lg mt-7 p-3\"</span><span class=\"token operator\">></span>\n      <span class=\"token operator\">&#x3C;</span>h1 className<span class=\"token operator\">=</span><span class=\"token string\">'text-3xl mb-3 text-center'</span><span class=\"token operator\">></span>Register<span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>h1<span class=\"token operator\">></span>\n        <span class=\"token operator\">&#x3C;</span>div className<span class=\"token operator\">=</span><span class=\"token string\">'mb-4'</span><span class=\"token operator\">></span>\n          <span class=\"token operator\">&#x3C;</span>label <span class=\"token keyword\">for</span><span class=\"token operator\">=</span><span class=\"token string\">\"name\"</span><span class=\"token operator\">></span>Full Name<span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>label<span class=\"token operator\">></span>\n          <span class=\"token operator\">&#x3C;</span>input type<span class=\"token operator\">=</span><span class=\"token string\">\"text\"</span> name<span class=\"token operator\">=</span><span class=\"token string\">\"name\"</span> id<span class=\"token operator\">=</span><span class=\"token string\">\"name\"</span> \n            className<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span><span class=\"token template-string\"><span class=\"token template-punctuation string\">`</span><span class=\"token string\">block w-full rounded border py-1 px-2 </span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${</span>formik<span class=\"token punctuation\">.</span>touched<span class=\"token punctuation\">.</span>name <span class=\"token operator\">&#x26;&#x26;</span> formik<span class=\"token punctuation\">.</span>errors<span class=\"token punctuation\">.</span>name <span class=\"token operator\">?</span> <span class=\"token string\">'border-red-400'</span> <span class=\"token operator\">:</span> <span class=\"token string\">'border-gray-300'</span><span class=\"token interpolation-punctuation punctuation\">}</span></span><span class=\"token template-punctuation string\">`</span></span><span class=\"token punctuation\">}</span>\n            onChange<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span>formik<span class=\"token punctuation\">.</span>handleChange<span class=\"token punctuation\">}</span> onBlur<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span>formik<span class=\"token punctuation\">.</span>handleBlur<span class=\"token punctuation\">}</span> value<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span>formik<span class=\"token punctuation\">.</span>values<span class=\"token punctuation\">.</span>name<span class=\"token punctuation\">}</span> <span class=\"token operator\">/</span><span class=\"token operator\">></span>\n          <span class=\"token punctuation\">{</span>formik<span class=\"token punctuation\">.</span>touched<span class=\"token punctuation\">.</span>name <span class=\"token operator\">&#x26;&#x26;</span> formik<span class=\"token punctuation\">.</span>errors<span class=\"token punctuation\">.</span>name <span class=\"token operator\">&#x26;&#x26;</span> <span class=\"token punctuation\">(</span>\n            <span class=\"token operator\">&#x3C;</span>span className<span class=\"token operator\">=</span><span class=\"token string\">'text-red-400'</span><span class=\"token operator\">></span><span class=\"token punctuation\">{</span>formik<span class=\"token punctuation\">.</span>errors<span class=\"token punctuation\">.</span>name<span class=\"token punctuation\">}</span><span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>span<span class=\"token operator\">></span>\n          <span class=\"token punctuation\">)</span><span class=\"token punctuation\">}</span>\n        <span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>div<span class=\"token operator\">></span>\n        <span class=\"token operator\">&#x3C;</span>div className<span class=\"token operator\">=</span><span class=\"token string\">'mb-4'</span><span class=\"token operator\">></span>\n          <span class=\"token operator\">&#x3C;</span>label <span class=\"token keyword\">for</span><span class=\"token operator\">=</span><span class=\"token string\">\"email\"</span><span class=\"token operator\">></span>Email<span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>label<span class=\"token operator\">></span>\n          <span class=\"token operator\">&#x3C;</span>input type<span class=\"token operator\">=</span><span class=\"token string\">\"email\"</span> name<span class=\"token operator\">=</span><span class=\"token string\">\"email\"</span> id<span class=\"token operator\">=</span><span class=\"token string\">\"email\"</span>\n            className<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span><span class=\"token template-string\"><span class=\"token template-punctuation string\">`</span><span class=\"token string\">block w-full rounded border py-1 px-2 </span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${</span>formik<span class=\"token punctuation\">.</span>touched<span class=\"token punctuation\">.</span>email <span class=\"token operator\">&#x26;&#x26;</span> formik<span class=\"token punctuation\">.</span>errors<span class=\"token punctuation\">.</span>email <span class=\"token operator\">?</span> <span class=\"token string\">'border-red-400'</span> <span class=\"token operator\">:</span> <span class=\"token string\">'border-gray-300'</span><span class=\"token interpolation-punctuation punctuation\">}</span></span><span class=\"token template-punctuation string\">`</span></span><span class=\"token punctuation\">}</span>\n            onChange<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span>formik<span class=\"token punctuation\">.</span>handleChange<span class=\"token punctuation\">}</span> onBlur<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span>formik<span class=\"token punctuation\">.</span>handleBlur<span class=\"token punctuation\">}</span> value<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span>formik<span class=\"token punctuation\">.</span>values<span class=\"token punctuation\">.</span>email<span class=\"token punctuation\">}</span> <span class=\"token operator\">/</span><span class=\"token operator\">></span>\n          <span class=\"token punctuation\">{</span>formik<span class=\"token punctuation\">.</span>touched<span class=\"token punctuation\">.</span>email <span class=\"token operator\">&#x26;&#x26;</span> formik<span class=\"token punctuation\">.</span>errors<span class=\"token punctuation\">.</span>email <span class=\"token operator\">&#x26;&#x26;</span> <span class=\"token punctuation\">(</span>\n            <span class=\"token operator\">&#x3C;</span>span className<span class=\"token operator\">=</span><span class=\"token string\">'text-red-400'</span><span class=\"token operator\">></span><span class=\"token punctuation\">{</span>formik<span class=\"token punctuation\">.</span>errors<span class=\"token punctuation\">.</span>email<span class=\"token punctuation\">}</span><span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>span<span class=\"token operator\">></span>\n          <span class=\"token punctuation\">)</span><span class=\"token punctuation\">}</span>\n        <span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>div<span class=\"token operator\">></span>\n        <span class=\"token operator\">&#x3C;</span>div className<span class=\"token operator\">=</span><span class=\"token string\">'mb-4'</span><span class=\"token operator\">></span>\n          <span class=\"token operator\">&#x3C;</span>label <span class=\"token keyword\">for</span><span class=\"token operator\">=</span><span class=\"token string\">\"profession\"</span><span class=\"token operator\">></span>Profession<span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>label<span class=\"token operator\">></span>\n          <span class=\"token operator\">&#x3C;</span>select name<span class=\"token operator\">=</span><span class=\"token string\">\"profession\"</span> id<span class=\"token operator\">=</span><span class=\"token string\">\"profession\"</span>\n            className<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span><span class=\"token template-string\"><span class=\"token template-punctuation string\">`</span><span class=\"token string\">block w-full rounded border py-1 px-2 </span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${</span>formik<span class=\"token punctuation\">.</span>touched<span class=\"token punctuation\">.</span>profession <span class=\"token operator\">&#x26;&#x26;</span> formik<span class=\"token punctuation\">.</span>errors<span class=\"token punctuation\">.</span>profession <span class=\"token operator\">?</span> <span class=\"token string\">'border-red-400'</span> <span class=\"token operator\">:</span> <span class=\"token string\">'border-gray-300'</span><span class=\"token interpolation-punctuation punctuation\">}</span></span><span class=\"token template-punctuation string\">`</span></span><span class=\"token punctuation\">}</span>\n            onChange<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span>formik<span class=\"token punctuation\">.</span>handleChange<span class=\"token punctuation\">}</span> onBlur<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span>formik<span class=\"token punctuation\">.</span>handleBlur<span class=\"token punctuation\">}</span> value<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span>formik<span class=\"token punctuation\">.</span>values<span class=\"token punctuation\">.</span>profession<span class=\"token punctuation\">}</span> <span class=\"token operator\">></span>\n            <span class=\"token punctuation\">{</span>professions<span class=\"token punctuation\">.</span><span class=\"token function\">map</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">profession<span class=\"token punctuation\">,</span> index</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">(</span>\n              <span class=\"token operator\">&#x3C;</span>option value<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span>profession<span class=\"token punctuation\">}</span> key<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span>index<span class=\"token punctuation\">}</span><span class=\"token operator\">></span><span class=\"token punctuation\">{</span>profession<span class=\"token punctuation\">}</span><span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>option<span class=\"token operator\">></span>\n            <span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">}</span>\n          <span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>select<span class=\"token operator\">></span>\n          <span class=\"token punctuation\">{</span>formik<span class=\"token punctuation\">.</span>touched<span class=\"token punctuation\">.</span>profession <span class=\"token operator\">&#x26;&#x26;</span> formik<span class=\"token punctuation\">.</span>errors<span class=\"token punctuation\">.</span>profession <span class=\"token operator\">&#x26;&#x26;</span> <span class=\"token punctuation\">(</span>\n            <span class=\"token operator\">&#x3C;</span>span className<span class=\"token operator\">=</span><span class=\"token string\">'text-red-400'</span><span class=\"token operator\">></span><span class=\"token punctuation\">{</span>formik<span class=\"token punctuation\">.</span>errors<span class=\"token punctuation\">.</span>profession<span class=\"token punctuation\">}</span><span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>span<span class=\"token operator\">></span>\n          <span class=\"token punctuation\">)</span><span class=\"token punctuation\">}</span>\n        <span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>div<span class=\"token operator\">></span>\n        <span class=\"token operator\">&#x3C;</span>div className<span class=\"token operator\">=</span><span class=\"token string\">'mb-4'</span><span class=\"token operator\">></span>\n          <span class=\"token operator\">&#x3C;</span>label <span class=\"token keyword\">for</span><span class=\"token operator\">=</span><span class=\"token string\">\"age\"</span><span class=\"token operator\">></span>Age<span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>label<span class=\"token operator\">></span>\n          <span class=\"token operator\">&#x3C;</span>input type<span class=\"token operator\">=</span><span class=\"token string\">\"number\"</span> name<span class=\"token operator\">=</span><span class=\"token string\">\"age\"</span> id<span class=\"token operator\">=</span><span class=\"token string\">\"age\"</span>\n            className<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span><span class=\"token template-string\"><span class=\"token template-punctuation string\">`</span><span class=\"token string\">block w-full rounded border py-1 px-2 </span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${</span>formik<span class=\"token punctuation\">.</span>touched<span class=\"token punctuation\">.</span>age <span class=\"token operator\">&#x26;&#x26;</span> formik<span class=\"token punctuation\">.</span>errors<span class=\"token punctuation\">.</span>age <span class=\"token operator\">?</span> <span class=\"token string\">'border-red-400'</span> <span class=\"token operator\">:</span> <span class=\"token string\">'border-gray-300'</span><span class=\"token interpolation-punctuation punctuation\">}</span></span><span class=\"token template-punctuation string\">`</span></span><span class=\"token punctuation\">}</span>\n            onChange<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span>formik<span class=\"token punctuation\">.</span>handleChange<span class=\"token punctuation\">}</span> onBlur<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span>formik<span class=\"token punctuation\">.</span>handleBlur<span class=\"token punctuation\">}</span> value<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span>formik<span class=\"token punctuation\">.</span>values<span class=\"token punctuation\">.</span>age<span class=\"token punctuation\">}</span> <span class=\"token operator\">/</span><span class=\"token operator\">></span>\n          <span class=\"token punctuation\">{</span>formik<span class=\"token punctuation\">.</span>touched<span class=\"token punctuation\">.</span>age <span class=\"token operator\">&#x26;&#x26;</span> formik<span class=\"token punctuation\">.</span>errors<span class=\"token punctuation\">.</span>age <span class=\"token operator\">&#x26;&#x26;</span> <span class=\"token punctuation\">(</span>\n            <span class=\"token operator\">&#x3C;</span>span className<span class=\"token operator\">=</span><span class=\"token string\">'text-red-400'</span><span class=\"token operator\">></span><span class=\"token punctuation\">{</span>formik<span class=\"token punctuation\">.</span>errors<span class=\"token punctuation\">.</span>age<span class=\"token punctuation\">}</span><span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>span<span class=\"token operator\">></span>\n          <span class=\"token punctuation\">)</span><span class=\"token punctuation\">}</span>\n        <span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>div<span class=\"token operator\">></span>\n        <span class=\"token operator\">&#x3C;</span>div className<span class=\"token operator\">=</span><span class=\"token string\">'text-center'</span><span class=\"token operator\">></span>\n          <span class=\"token operator\">&#x3C;</span>button className<span class=\"token operator\">=</span><span class=\"token string\">'bg-blue-500 rounded p-3 text-white'</span> type<span class=\"token operator\">=</span><span class=\"token string\">'submit'</span><span class=\"token operator\">></span>Submit<span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>button<span class=\"token operator\">></span>\n        <span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>div<span class=\"token operator\">></span>\n      <span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>form<span class=\"token operator\">></span>\n    <span class=\"token operator\">&#x3C;</span><span class=\"token operator\">/</span>div<span class=\"token operator\">></span>\n  <span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div><p>Notice how you used all the properties in the <code class=\"language-text\">formik</code> variable mentioned earlier.</p><h3 id=\"test-it-out\">Test it Out</h3><p>The form is now created and ready to be used, even if there's no validation yet.</p><p>To test it out, run the server using the following command:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\"><span class=\"token function\">npm</span> start</code></pre></div><p>You can then open the website at <code class=\"language-text\">localhost:3000</code> (default port). If you open the website, you'll see the form with 4 fields.</p><figure class=\"kg-card kg-image-card\"><img src=\"https://backend.shahednasser.com/content/images/2022/03/Screen-Shot-2022-03-19-at-2.49.28-PM-1.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"1084\" height=\"900\"></figure><p>You can try and fill out the form. As currently there's no validation, you can fill out (or not) values as you want and click Submit. An alert will show with the values you entered.</p><figure class=\"kg-card kg-image-card\"><img src=\"https://backend.shahednasser.com/content/images/2022/03/Screen-Shot-2022-03-19-at-2.50.35-PM-1.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"1010\" height=\"410\"></figure><h2 id=\"add-validation-with-yup\">Add Validation with Yup</h2><p>In this section, you'll add validation to the form using Yup.</p><p>First, you need to install Yup. Run the following in your terminal:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\"><span class=\"token function\">npm</span> i yup</code></pre></div><p>Yup has a lot of <a href=\"https://github.com/jquense/yup#table-of-contents\">methods and validation rules</a> you can use. The way it works with Formik is you need to create a validation schema and pass it to <code class=\"language-text\">useFormik</code> as a value to the property <code class=\"language-text\">validationSchema</code>.</p><p>Yup validation schemas are created using <code class=\"language-text\">Yup.object</code> method which takes as a parameter an object. This object has the field names as properties and their values are validation rules from the Yup library.</p><p>Import Yup at the beginning of <code class=\"language-text\">src/App.js</code>:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">import</span> <span class=\"token operator\">*</span> <span class=\"token keyword\">as</span> Yup <span class=\"token keyword\">from</span> <span class=\"token string\">'yup'</span><span class=\"token punctuation\">;</span></code></pre></div><p>Then, add the property <code class=\"language-text\">validationSchema</code> to the object passed to <code class=\"language-text\">useFormik</code> with the following value:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">const</span> formik <span class=\"token operator\">=</span> <span class=\"token function\">useFormik</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>\n    <span class=\"token operator\">...</span><span class=\"token punctuation\">,</span>\n    <span class=\"token literal-property property\">validationSchema</span><span class=\"token operator\">:</span> Yup<span class=\"token punctuation\">.</span><span class=\"token function\">object</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>\n      <span class=\"token literal-property property\">name</span><span class=\"token operator\">:</span> Yup<span class=\"token punctuation\">.</span><span class=\"token function\">string</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n              <span class=\"token punctuation\">.</span><span class=\"token function\">label</span><span class=\"token punctuation\">(</span><span class=\"token string\">'Full Name'</span><span class=\"token punctuation\">)</span>\n              <span class=\"token punctuation\">.</span><span class=\"token function\">required</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n      <span class=\"token literal-property property\">email</span><span class=\"token operator\">:</span> Yup<span class=\"token punctuation\">.</span><span class=\"token function\">string</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n              <span class=\"token punctuation\">.</span><span class=\"token function\">email</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n              <span class=\"token punctuation\">.</span><span class=\"token function\">required</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n      <span class=\"token literal-property property\">profession</span><span class=\"token operator\">:</span> Yup<span class=\"token punctuation\">.</span><span class=\"token function\">string</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n                  <span class=\"token punctuation\">.</span><span class=\"token function\">oneOf</span><span class=\"token punctuation\">(</span>professions<span class=\"token punctuation\">,</span> <span class=\"token string\">'The profession you chose does not exist'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n      <span class=\"token literal-property property\">age</span><span class=\"token operator\">:</span> Yup<span class=\"token punctuation\">.</span><span class=\"token function\">number</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n            <span class=\"token punctuation\">.</span><span class=\"token function\">min</span><span class=\"token punctuation\">(</span><span class=\"token number\">15</span><span class=\"token punctuation\">,</span> <span class=\"token string\">'You need to be older than 15 to register'</span><span class=\"token punctuation\">)</span>\n            <span class=\"token punctuation\">.</span><span class=\"token function\">required</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span></code></pre></div><p>You add the following validation rules:</p><ol><li><code class=\"language-text\">name</code>: Should be a string and is required. You also use the <code class=\"language-text\">label</code> method to ensure that when the error message is shown it refers to the field as \"Full Name\". By default, the fields are referred to by the field name, which in this case is <code class=\"language-text\">name</code>.</li><li><code class=\"language-text\">email</code>: Should be a string, an email, and required.</li><li><code class=\"language-text\">profession</code>: Should be a string and one of the values in the <code class=\"language-text\">professions</code> array. You also pass a message as a second parameter to <code class=\"language-text\">oneOf</code> which will be the message that shows in case there's an error. It's also required.</li><li><code class=\"language-text\">age</code>: Should be a number and at least 15. If the age is less than 15, the message \"You need to be older than 15 to register\" will show. It's also required.</li></ol><h3 id=\"test-it-out-1\">Test it Out</h3><p>Let's test it out. Run the server again if it's not running and open the website. If you enter values now that don't comply with the rules you set in the validation schema, an error will show in red and you won't be able to submit the form before resolving the errors.</p><figure class=\"kg-card kg-image-card\"><img src=\"https://backend.shahednasser.com/content/images/2022/03/Screen-Shot-2022-03-19-at-2.55.58-PM-1.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"1102\" height=\"938\"></figure><p>If you all values are valid, then the form will be submitted and an alert will show.</p><h3 id=\"custom-validation-rules\">Custom Validation Rules</h3><p>Although Yup has helpful validation rules that you can use with most common cases, a lot of times you might need a custom validation rule. You can use the <a href=\"https://github.com/jquense/yup#schematestname-string-message-string--function--any-test-function-schema\">test</a> function to add a custom rule.</p><p>In this section, you'll add a rule to make sure that the <code class=\"language-text\">name</code> field has both first and last name.</p><p>Change the <code class=\"language-text\">name</code> property inside the <code class=\"language-text\">validationSchema</code> to the following:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token keyword\">const</span> formik <span class=\"token operator\">=</span> <span class=\"token function\">useFormik</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>\n    <span class=\"token operator\">...</span><span class=\"token punctuation\">,</span>\n    <span class=\"token literal-property property\">validationSchema</span><span class=\"token operator\">:</span> Yup<span class=\"token punctuation\">.</span><span class=\"token function\">object</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>\n      <span class=\"token literal-property property\">name</span><span class=\"token operator\">:</span> Yup<span class=\"token punctuation\">.</span><span class=\"token function\">string</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n              <span class=\"token punctuation\">.</span><span class=\"token function\">label</span><span class=\"token punctuation\">(</span><span class=\"token string\">'Full Name'</span><span class=\"token punctuation\">)</span>\n              <span class=\"token punctuation\">.</span><span class=\"token function\">required</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n              <span class=\"token punctuation\">.</span><span class=\"token function\">test</span><span class=\"token punctuation\">(</span><span class=\"token string\">'is-full-name'</span><span class=\"token punctuation\">,</span> <span class=\"token string\">'Please enter both your first and last name'</span><span class=\"token punctuation\">,</span> <span class=\"token keyword\">function</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">value</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n                <span class=\"token keyword\">const</span> nameArr <span class=\"token operator\">=</span> value<span class=\"token punctuation\">.</span><span class=\"token function\">split</span><span class=\"token punctuation\">(</span><span class=\"token string\">\" \"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n                <span class=\"token keyword\">return</span> nameArr<span class=\"token punctuation\">.</span>length <span class=\"token operator\">>=</span> <span class=\"token number\">2</span><span class=\"token punctuation\">;</span>\n              <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n      <span class=\"token operator\">...</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span></code></pre></div><p>The first parameter is the name of the custom rule. The second parameter is the message to show in case the field is invalid. </p><p>The third parameter is the function that determines whether the field is valid or not. It should return a boolean value. If the value is true, then the field is valid. Otherwise, it's invalid.</p><p>You validate the name field to contain both first and last names by just splitting it  on the space delimiter which will return an array. You then check the array length. If it's at least 2, then the field is valid. Otherwise it's invalid.</p><h3 id=\"test-it-out-2\">Test it Out</h3><p>Run the server again now and go to the website. If you enter one word in the Full Name field you'll see an error.</p><figure class=\"kg-card kg-image-card\"><img src=\"https://backend.shahednasser.com/content/images/2022/03/us9mldxrs5dvf174r4w9.png.jpeg\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"880\" height=\"192\"></figure><p>You'll need to enter at least two words for the field to be valid.</p><h2 id=\"conclusion\">Conclusion</h2><p>In this tutorial you learned how to use Formik and Yup in React. You can use these two libraries to create forms, validate them, and handle their submission. Using these two libraries makes creating forms in React easier and less stressful.</p>","htmlAst":{"type":"root","children":[{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Perhaps one of the most annoying tasks in React is creating forms and validating them, especially if you're doing it without using any libraries. You'll have to manage the states, values, and validation of all inputs."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"a","properties":{"href":"https://formik.org"},"children":[{"type":"text","value":"Formik"}]},{"type":"text","value":" is a React and React Native library that helps you create forms in React \"without the tears\". You can pair Formik with validation libraries like "},{"type":"element","tagName":"a","properties":{"href":"https://github.com/jquense/yup"},"children":[{"type":"text","value":"Yup"}]},{"type":"text","value":" to make the process even simpler."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"In this tutorial, you'll learn how creating and validating forms can be simpler in React using Formik and Yup. You'll create a simple form with different types of fields and see the different ways you can validate that form."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"You can find the code for this tutorial in "},{"type":"element","tagName":"a","properties":{"href":"https://github.com/shahednasser/react-forms-tutorial"},"children":[{"type":"text","value":"this GitHub repository"}]},{"type":"text","value":"."}]},{"type":"element","tagName":"h2","properties":{"id":"project-setup"},"children":[{"type":"text","value":"Project Setup"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"In this section, you'll set up your website using "},{"type":"element","tagName":"a","properties":{"href":"https://create-react-app.dev"},"children":[{"type":"text","value":"Create React App"}]},{"type":"text","value":" (CRA) and install some dependencies for the sake of the tutorial. If you already have a website set up you can skip this part."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"In your terminal, run the following command to create a new React website with CRA:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"bash"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-bash"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-bash"]},"children":[{"type":"text","value":"npx create-react-app react-forms"}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"I'm calling the website "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"react-forms"}]},{"type":"text","value":" but you can change it to whatever you want."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Once the installation is done, change to the newly created directory:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"bash"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-bash"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-bash"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","builtin","class-name"]},"children":[{"type":"text","value":"cd"}]},{"type":"text","value":" react-forms"}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Then, install "},{"type":"element","tagName":"a","properties":{"href":"https://tailwindcss.com"},"children":[{"type":"text","value":"Tailwind CSS"}]},{"type":"text","value":" to add some styling to your website:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"bash"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-bash"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-bash"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"npm"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"install"}]},{"type":"text","value":" -D tailwindcss postcss autoprefixer"}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"To set up Tailwind CSS create the file "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"tailwind.config.js"}]},{"type":"text","value":" with the following content:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"bash"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-bash"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-bash"]},"children":[{"type":"text","value":"module.exports "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n  content: "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"["}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"./src/**/*.{js,jsx,ts,tsx}\""}]},{"type":"text","value":",\n  "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"]"}]},{"type":"text","value":",\n  theme: "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n    extend: "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":",\n  "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":",\n  plugins: "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"["}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"]"}]},{"type":"text","value":",\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"And replace the content of "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"src/index.css"}]},{"type":"text","value":" with the following:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"bash"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-bash"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-bash"]},"children":[{"type":"text","value":"@tailwind base"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n@tailwind components"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n@tailwind utilities"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]}]}]}]},{"type":"element","tagName":"h2","properties":{"id":"create-the-form-with-formik"},"children":[{"type":"text","value":"Create the Form with Formik"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"You'll now use Formik to create a form. First, install Formik:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"bash"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-bash"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-bash"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"npm"}]},{"type":"text","value":" i formik"}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Replace the content of "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"src/App.js"}]},{"type":"text","value":" with the following:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"import"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" useFormik "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"from"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'formik'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"function"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"App"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" professions "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"["}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'Developer'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'Designer'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'Other'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"]"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"//TODO create formik instance"}]},{"type":"text","value":"\n    \n    "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"\n    \t"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"div className"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"bg-blue-300 min-w-screen min-h-screen overflow-x-hidden\""}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"div"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"export"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"default"}]},{"type":"text","value":" App"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"All you did here is create the component App which does nothing special at the moment."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Notice how you import the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"useFormik"}]},{"type":"text","value":" hook at the beginning of the file. You'll use this hook to create a Formik instance with all the states and helpers you'll need."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"The "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"useFormik"}]},{"type":"text","value":" hook accepts as a parameter an object of "},{"type":"element","tagName":"a","properties":{"href":"https://formik.org/docs/api/formik#props-1"},"children":[{"type":"text","value":"configurations"}]},{"type":"text","value":". These configurations can be used to modify and shape your form as you need."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"In this tutorial, you'll use the pass the following properties in the object:"}]},{"type":"element","tagName":"ol","properties":{},"children":[{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"initialValues"}]},{"type":"text","value":": includes the form fields and their initial values."}]},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"validationSchema"}]},{"type":"text","value":": A Yup schema to validate the fields. You'll use this in the next section."}]},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"onSubmit"}]},{"type":"text","value":": a function to execute when the form is submitted."}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Replace the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"TODO"}]},{"type":"text","value":" in the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"App"}]},{"type":"text","value":" component with the following:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" formik "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"useFormik"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"initialValues"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"name"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"''"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"email"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"''"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"profession"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" professions"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"["}]},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"0"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"]"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"age"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"''"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","function-variable","function"]},"children":[{"type":"text","value":"onSubmit"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"function"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"values"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"alert"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","template-string"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","template-punctuation","string"]},"children":[{"type":"text","value":"`"}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"You are registered! Name: "}]},{"type":"element","tagName":"span","properties":{"className":["token","interpolation"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","interpolation-punctuation","punctuation"]},"children":[{"type":"text","value":"${"}]},{"type":"text","value":"values"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"name"},{"type":"element","tagName":"span","properties":{"className":["token","interpolation-punctuation","punctuation"]},"children":[{"type":"text","value":"}"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":". Email: "}]},{"type":"element","tagName":"span","properties":{"className":["token","interpolation"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","interpolation-punctuation","punctuation"]},"children":[{"type":"text","value":"${"}]},{"type":"text","value":"values"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"email"},{"type":"element","tagName":"span","properties":{"className":["token","interpolation-punctuation","punctuation"]},"children":[{"type":"text","value":"}"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":". Profession: "}]},{"type":"element","tagName":"span","properties":{"className":["token","interpolation"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","interpolation-punctuation","punctuation"]},"children":[{"type":"text","value":"${"}]},{"type":"text","value":"values"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"profession"},{"type":"element","tagName":"span","properties":{"className":["token","interpolation-punctuation","punctuation"]},"children":[{"type":"text","value":"}"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":". \n        Age: "}]},{"type":"element","tagName":"span","properties":{"className":["token","interpolation"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","interpolation-punctuation","punctuation"]},"children":[{"type":"text","value":"${"}]},{"type":"text","value":"values"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"age"},{"type":"element","tagName":"span","properties":{"className":["token","interpolation-punctuation","punctuation"]},"children":[{"type":"text","value":"}"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","template-punctuation","string"]},"children":[{"type":"text","value":"`"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"As you can see, you set the value of the property "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"initialValues"}]},{"type":"text","value":" to an object. This object's keys are the names of the fields in the form. Their values are the initial value."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"In the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"onSubmit"}]},{"type":"text","value":" function, you receive the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"values"}]},{"type":"text","value":" object as a parameter. Here you can access the values and use them to save them in the database or send them to a server. For the sake of this tutorial, you just print them out in an alert."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Note that the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"onSubmit"}]},{"type":"text","value":" function is only executed once the form is validated. So, you don't need to perform any validation inside this function."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Now, you can use the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"formik"}]},{"type":"text","value":" variable to create a form, link its fields to the fields you defined in "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"useFormik"}]},{"type":"text","value":", link the validation, and link the submit handler."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"formik"}]},{"type":"text","value":" includes the following properties among "},{"type":"element","tagName":"a","properties":{"href":"https://formik.org/docs/api/formik#props-1"},"children":[{"type":"text","value":"others"}]},{"type":"text","value":":"}]},{"type":"element","tagName":"ol","properties":{},"children":[{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"handleSubmit"}]},{"type":"text","value":": the submit function that should be called when the form is submitted. This is usually assigned to the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"onSubmit"}]},{"type":"text","value":" event handler of "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"form"}]},{"type":"text","value":" elements."}]},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"errors"}]},{"type":"text","value":": An object that has the field names as properties and the value of each is the error message resulted from validating that field if there are any errors."}]},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"touched"}]},{"type":"text","value":": An object that has the field names as properties and the value is a boolean indicating whether the user has interacted with the field or not."}]},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"values"}]},{"type":"text","value":": An object that has the field names as properties and the value of each is the current value of that field. It's usually used to set the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"value"}]},{"type":"text","value":" property of input elements."}]},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"handleChange"}]},{"type":"text","value":": A function that should be used as the handler of the change event of input elements. It's passed as the value of the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"onChange"}]},{"type":"text","value":" prop of elements."}]},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"handleBlur"}]},{"type":"text","value":": A function that should be used as the handler of the blur event of input elements. It's passed as the value of the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"onBlur"}]},{"type":"text","value":" prop of elements."}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Replace the return statement in "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"App"}]},{"type":"text","value":" with the following:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"div className"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"bg-blue-300 min-w-screen min-h-screen overflow-x-hidden\""}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"form onSubmit"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"formik"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"handleSubmit"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" className"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"max-w-lg mx-auto bg-white rounded shadow-lg mt-7 p-3\""}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"h1 className"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'text-3xl mb-3 text-center'"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"Register"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"h1"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"div className"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'mb-4'"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n          "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"label "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"for"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"name\""}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"Full Name"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"label"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n          "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"input type"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"text\""}]},{"type":"text","value":" name"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"name\""}]},{"type":"text","value":" id"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"name\""}]},{"type":"text","value":" \n            className"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"element","tagName":"span","properties":{"className":["token","template-string"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","template-punctuation","string"]},"children":[{"type":"text","value":"`"}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"block w-full rounded border py-1 px-2 "}]},{"type":"element","tagName":"span","properties":{"className":["token","interpolation"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","interpolation-punctuation","punctuation"]},"children":[{"type":"text","value":"${"}]},{"type":"text","value":"formik"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"touched"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"name "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"&&"}]},{"type":"text","value":" formik"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"errors"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"name "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"?"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'border-red-400'"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'border-gray-300'"}]},{"type":"element","tagName":"span","properties":{"className":["token","interpolation-punctuation","punctuation"]},"children":[{"type":"text","value":"}"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","template-punctuation","string"]},"children":[{"type":"text","value":"`"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n            onChange"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"formik"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"handleChange"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" onBlur"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"formik"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"handleBlur"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" value"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"formik"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"values"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"name"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n          "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"formik"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"touched"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"name "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"&&"}]},{"type":"text","value":" formik"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"errors"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"name "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"&&"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"\n            "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"span className"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'text-red-400'"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"formik"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"errors"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"name"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"span"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n          "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"div"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"div className"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'mb-4'"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n          "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"label "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"for"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"email\""}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"Email"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"label"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n          "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"input type"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"email\""}]},{"type":"text","value":" name"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"email\""}]},{"type":"text","value":" id"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"email\""}]},{"type":"text","value":"\n            className"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"element","tagName":"span","properties":{"className":["token","template-string"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","template-punctuation","string"]},"children":[{"type":"text","value":"`"}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"block w-full rounded border py-1 px-2 "}]},{"type":"element","tagName":"span","properties":{"className":["token","interpolation"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","interpolation-punctuation","punctuation"]},"children":[{"type":"text","value":"${"}]},{"type":"text","value":"formik"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"touched"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"email "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"&&"}]},{"type":"text","value":" formik"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"errors"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"email "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"?"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'border-red-400'"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'border-gray-300'"}]},{"type":"element","tagName":"span","properties":{"className":["token","interpolation-punctuation","punctuation"]},"children":[{"type":"text","value":"}"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","template-punctuation","string"]},"children":[{"type":"text","value":"`"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n            onChange"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"formik"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"handleChange"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" onBlur"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"formik"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"handleBlur"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" value"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"formik"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"values"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"email"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n          "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"formik"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"touched"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"email "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"&&"}]},{"type":"text","value":" formik"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"errors"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"email "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"&&"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"\n            "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"span className"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'text-red-400'"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"formik"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"errors"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"email"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"span"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n          "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"div"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"div className"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'mb-4'"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n          "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"label "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"for"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"profession\""}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"Profession"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"label"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n          "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"select name"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"profession\""}]},{"type":"text","value":" id"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"profession\""}]},{"type":"text","value":"\n            className"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"element","tagName":"span","properties":{"className":["token","template-string"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","template-punctuation","string"]},"children":[{"type":"text","value":"`"}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"block w-full rounded border py-1 px-2 "}]},{"type":"element","tagName":"span","properties":{"className":["token","interpolation"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","interpolation-punctuation","punctuation"]},"children":[{"type":"text","value":"${"}]},{"type":"text","value":"formik"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"touched"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"profession "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"&&"}]},{"type":"text","value":" formik"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"errors"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"profession "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"?"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'border-red-400'"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'border-gray-300'"}]},{"type":"element","tagName":"span","properties":{"className":["token","interpolation-punctuation","punctuation"]},"children":[{"type":"text","value":"}"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","template-punctuation","string"]},"children":[{"type":"text","value":"`"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n            onChange"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"formik"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"handleChange"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" onBlur"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"formik"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"handleBlur"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" value"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"formik"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"values"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"profession"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n            "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"professions"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"map"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"profession"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" index"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"\n              "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"option value"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"profession"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" key"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"index"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"profession"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"option"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n            "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n          "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"select"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n          "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"formik"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"touched"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"profession "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"&&"}]},{"type":"text","value":" formik"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"errors"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"profession "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"&&"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"\n            "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"span className"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'text-red-400'"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"formik"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"errors"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"profession"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"span"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n          "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"div"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"div className"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'mb-4'"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n          "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"label "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"for"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"age\""}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"Age"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"label"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n          "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"input type"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"number\""}]},{"type":"text","value":" name"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"age\""}]},{"type":"text","value":" id"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"age\""}]},{"type":"text","value":"\n            className"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"element","tagName":"span","properties":{"className":["token","template-string"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","template-punctuation","string"]},"children":[{"type":"text","value":"`"}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"block w-full rounded border py-1 px-2 "}]},{"type":"element","tagName":"span","properties":{"className":["token","interpolation"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","interpolation-punctuation","punctuation"]},"children":[{"type":"text","value":"${"}]},{"type":"text","value":"formik"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"touched"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"age "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"&&"}]},{"type":"text","value":" formik"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"errors"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"age "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"?"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'border-red-400'"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'border-gray-300'"}]},{"type":"element","tagName":"span","properties":{"className":["token","interpolation-punctuation","punctuation"]},"children":[{"type":"text","value":"}"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","template-punctuation","string"]},"children":[{"type":"text","value":"`"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n            onChange"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"formik"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"handleChange"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" onBlur"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"formik"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"handleBlur"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" value"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"formik"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"values"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"age"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n          "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"formik"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"touched"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"age "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"&&"}]},{"type":"text","value":" formik"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"errors"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"age "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"&&"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"\n            "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"span className"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'text-red-400'"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"formik"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"errors"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"age"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"span"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n          "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"div"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"div className"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'text-center'"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n          "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"button className"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'bg-blue-500 rounded p-3 text-white'"}]},{"type":"text","value":" type"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'submit'"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"Submit"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"button"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n        "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"div"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"form"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"<"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"/"}]},{"type":"text","value":"div"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Notice how you used all the properties in the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"formik"}]},{"type":"text","value":" variable mentioned earlier."}]},{"type":"element","tagName":"h3","properties":{"id":"test-it-out"},"children":[{"type":"text","value":"Test it Out"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"The form is now created and ready to be used, even if there's no validation yet."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"To test it out, run the server using the following command:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"bash"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-bash"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-bash"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"npm"}]},{"type":"text","value":" start"}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"You can then open the website at "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"localhost:3000"}]},{"type":"text","value":" (default port). If you open the website, you'll see the form with 4 fields."}]},{"type":"element","tagName":"figure","properties":{"className":["kg-card","kg-image-card"]},"children":[{"type":"element","tagName":"img","properties":{"src":"https://backend.shahednasser.com/content/images/2022/03/Screen-Shot-2022-03-19-at-2.49.28-PM-1.png","className":["kg-image"],"alt":"","loading":"lazy","width":1084,"height":900},"children":[]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"You can try and fill out the form. As currently there's no validation, you can fill out (or not) values as you want and click Submit. An alert will show with the values you entered."}]},{"type":"element","tagName":"figure","properties":{"className":["kg-card","kg-image-card"]},"children":[{"type":"element","tagName":"img","properties":{"src":"https://backend.shahednasser.com/content/images/2022/03/Screen-Shot-2022-03-19-at-2.50.35-PM-1.png","className":["kg-image"],"alt":"","loading":"lazy","width":1010,"height":410},"children":[]}]},{"type":"element","tagName":"h2","properties":{"id":"add-validation-with-yup"},"children":[{"type":"text","value":"Add Validation with Yup"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"In this section, you'll add validation to the form using Yup."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"First, you need to install Yup. Run the following in your terminal:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"bash"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-bash"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-bash"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"npm"}]},{"type":"text","value":" i yup"}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Yup has a lot of "},{"type":"element","tagName":"a","properties":{"href":"https://github.com/jquense/yup#table-of-contents"},"children":[{"type":"text","value":"methods and validation rules"}]},{"type":"text","value":" you can use. The way it works with Formik is you need to create a validation schema and pass it to "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"useFormik"}]},{"type":"text","value":" as a value to the property "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"validationSchema"}]},{"type":"text","value":"."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Yup validation schemas are created using "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"Yup.object"}]},{"type":"text","value":" method which takes as a parameter an object. This object has the field names as properties and their values are validation rules from the Yup library."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Import Yup at the beginning of "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"src/App.js"}]},{"type":"text","value":":"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"import"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"*"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"as"}]},{"type":"text","value":" Yup "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"from"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'yup'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Then, add the property "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"validationSchema"}]},{"type":"text","value":" to the object passed to "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"useFormik"}]},{"type":"text","value":" with the following value:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" formik "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"useFormik"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"..."}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"validationSchema"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" Yup"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"object"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"name"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" Yup"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"string"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n              "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"label"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'Full Name'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n              "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"required"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"email"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" Yup"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"string"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n              "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"email"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n              "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"required"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"profession"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" Yup"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"string"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n                  "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"oneOf"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"professions"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'The profession you chose does not exist'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"age"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" Yup"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"number"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n            "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"min"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"15"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'You need to be older than 15 to register'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n            "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"required"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"You add the following validation rules:"}]},{"type":"element","tagName":"ol","properties":{},"children":[{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"name"}]},{"type":"text","value":": Should be a string and is required. You also use the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"label"}]},{"type":"text","value":" method to ensure that when the error message is shown it refers to the field as \"Full Name\". By default, the fields are referred to by the field name, which in this case is "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"name"}]},{"type":"text","value":"."}]},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"email"}]},{"type":"text","value":": Should be a string, an email, and required."}]},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"profession"}]},{"type":"text","value":": Should be a string and one of the values in the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"professions"}]},{"type":"text","value":" array. You also pass a message as a second parameter to "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"oneOf"}]},{"type":"text","value":" which will be the message that shows in case there's an error. It's also required."}]},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"age"}]},{"type":"text","value":": Should be a number and at least 15. If the age is less than 15, the message \"You need to be older than 15 to register\" will show. It's also required."}]}]},{"type":"element","tagName":"h3","properties":{"id":"test-it-out-1"},"children":[{"type":"text","value":"Test it Out"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Let's test it out. Run the server again if it's not running and open the website. If you enter values now that don't comply with the rules you set in the validation schema, an error will show in red and you won't be able to submit the form before resolving the errors."}]},{"type":"element","tagName":"figure","properties":{"className":["kg-card","kg-image-card"]},"children":[{"type":"element","tagName":"img","properties":{"src":"https://backend.shahednasser.com/content/images/2022/03/Screen-Shot-2022-03-19-at-2.55.58-PM-1.png","className":["kg-image"],"alt":"","loading":"lazy","width":1102,"height":938},"children":[]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"If you all values are valid, then the form will be submitted and an alert will show."}]},{"type":"element","tagName":"h3","properties":{"id":"custom-validation-rules"},"children":[{"type":"text","value":"Custom Validation Rules"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Although Yup has helpful validation rules that you can use with most common cases, a lot of times you might need a custom validation rule. You can use the "},{"type":"element","tagName":"a","properties":{"href":"https://github.com/jquense/yup#schematestname-string-message-string--function--any-test-function-schema"},"children":[{"type":"text","value":"test"}]},{"type":"text","value":" function to add a custom rule."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"In this section, you'll add a rule to make sure that the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"name"}]},{"type":"text","value":" field has both first and last name."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Change the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"name"}]},{"type":"text","value":" property inside the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"validationSchema"}]},{"type":"text","value":" to the following:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" formik "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"useFormik"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"..."}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"validationSchema"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" Yup"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"object"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"name"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" Yup"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"string"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n              "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"label"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'Full Name'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n              "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"required"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n              "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"test"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'is-full-name'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'Please enter both your first and last name'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"function"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"value"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n                "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" nameArr "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" value"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"split"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\" \""}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n                "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" nameArr"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"length "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"2"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n              "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"..."}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"The first parameter is the name of the custom rule. The second parameter is the message to show in case the field is invalid. "}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"The third parameter is the function that determines whether the field is valid or not. It should return a boolean value. If the value is true, then the field is valid. Otherwise, it's invalid."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"You validate the name field to contain both first and last names by just splitting it  on the space delimiter which will return an array. You then check the array length. If it's at least 2, then the field is valid. Otherwise it's invalid."}]},{"type":"element","tagName":"h3","properties":{"id":"test-it-out-2"},"children":[{"type":"text","value":"Test it Out"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Run the server again now and go to the website. If you enter one word in the Full Name field you'll see an error."}]},{"type":"element","tagName":"figure","properties":{"className":["kg-card","kg-image-card"]},"children":[{"type":"element","tagName":"img","properties":{"src":"https://backend.shahednasser.com/content/images/2022/03/us9mldxrs5dvf174r4w9.png.jpeg","className":["kg-image"],"alt":"","loading":"lazy","width":880,"height":192},"children":[]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"You'll need to enter at least two words for the field to be valid."}]},{"type":"element","tagName":"h2","properties":{"id":"conclusion"},"children":[{"type":"text","value":"Conclusion"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"In this tutorial you learned how to use Formik and Yup in React. You can use these two libraries to create forms, validate them, and handle their submission. Using these two libraries makes creating forms in React easier and less stressful."}]}],"data":{"quirksMode":false}},"tableOfContents":[{"id":"project-setup","heading":"Project Setup"},{"id":"create-the-form-with-formik","heading":"Create the Form with Formik","items":[{"id":"test-it-out","heading":"Test it Out"}]},{"id":"add-validation-with-yup","heading":"Add Validation with Yup","items":[{"id":"test-it-out-1","heading":"Test it Out"},{"id":"custom-validation-rules","heading":"Custom Validation Rules"},{"id":"test-it-out-2","heading":"Test it Out"}]},{"id":"conclusion","heading":"Conclusion"}]},"featureImageSharp":{"base":"How-to-Create-and-Validate-Forms-in-React-using-Formik-and-Yup.webp","publicURL":"/static/91089d8a50da0ecc97647ef3cac82ba2/How-to-Create-and-Validate-Forms-in-React-using-Formik-and-Yup.webp","imageMeta":{"width":1000,"height":420},"childImageSharp":{"fluid":{"base64":"data:image/webp;base64,UklGRkgAAABXRUJQVlA4IDwAAABQAwCdASoUAAgAPtFWpEwoJKOiMAgBABoJaQAAW9PXmwi7AAD+8jvUupnDXapmZQhCREWIkppAgAX8AAA=","aspectRatio":2.364864864864865,"src":"/static/91089d8a50da0ecc97647ef3cac82ba2/89afa/How-to-Create-and-Validate-Forms-in-React-using-Formik-and-Yup.webp","srcSet":"/static/91089d8a50da0ecc97647ef3cac82ba2/9fca7/How-to-Create-and-Validate-Forms-in-React-using-Formik-and-Yup.webp 175w,\n/static/91089d8a50da0ecc97647ef3cac82ba2/37a4e/How-to-Create-and-Validate-Forms-in-React-using-Formik-and-Yup.webp 350w,\n/static/91089d8a50da0ecc97647ef3cac82ba2/89afa/How-to-Create-and-Validate-Forms-in-React-using-Formik-and-Yup.webp 700w,\n/static/91089d8a50da0ecc97647ef3cac82ba2/47f67/How-to-Create-and-Validate-Forms-in-React-using-Formik-and-Yup.webp 1000w","srcWebp":"/static/91089d8a50da0ecc97647ef3cac82ba2/89afa/How-to-Create-and-Validate-Forms-in-React-using-Formik-and-Yup.webp","srcSetWebp":"/static/91089d8a50da0ecc97647ef3cac82ba2/9fca7/How-to-Create-and-Validate-Forms-in-React-using-Formik-and-Yup.webp 175w,\n/static/91089d8a50da0ecc97647ef3cac82ba2/37a4e/How-to-Create-and-Validate-Forms-in-React-using-Formik-and-Yup.webp 350w,\n/static/91089d8a50da0ecc97647ef3cac82ba2/89afa/How-to-Create-and-Validate-Forms-in-React-using-Formik-and-Yup.webp 700w,\n/static/91089d8a50da0ecc97647ef3cac82ba2/47f67/How-to-Create-and-Validate-Forms-in-React-using-Formik-and-Yup.webp 1000w","sizes":"(max-width: 700px) 100vw, 700px"}}}}},{"node":{"id":"Ghost__Post__61efd82ce37d1cfea32a7e97","title":"How to Internationalize (i18n) a React App with Transifex Native","slug":"how-to-internationalize-i18n-a-react-app-with-transifex-native","featured":true,"feature_image":"https://backend.shahednasser.com/content/images/2022/01/How-to-Internationalize--i18n--a-React-App-with-Transifex-Native.jpg","excerpt":"In this article, you’ll learn how to internationalize a React app using Transifex Native.","custom_excerpt":"In this article, you’ll learn how to internationalize a React app using Transifex Native.","visibility":"public","created_at_pretty":"25 Jan 2022","published_at_pretty":"26 Jan 2022","updated_at_pretty":"26 Jan 2022","created_at":"2022-01-25T10:59:56.000+00:00","published_at":"2022-01-26T08:12:44.000+00:00","updated_at":"2022-01-26T09:40:17.000+00:00","meta_title":null,"meta_description":null,"og_description":null,"og_image":null,"og_title":null,"twitter_description":null,"twitter_image":null,"twitter_title":null,"authors":[{"slug":"shahed","url":"https://backend.shahednasser.com/author/shahed/","name":"Shahed Nasser","bio":null,"cover_image":null,"profile_image":"https://backend.shahednasser.com/content/images/2022/03/IMG_0591.jpg","location":null,"website":null,"twitter":null,"facebook":null,"meta_title":null,"meta_description":null,"coverImageSharp":null,"profileImageSharp":null}],"primary_author":{"slug":"shahed","url":"https://backend.shahednasser.com/author/shahed/","name":"Shahed Nasser","bio":null,"cover_image":null,"profile_image":"https://backend.shahednasser.com/content/images/2022/03/IMG_0591.jpg","location":null,"website":null,"twitter":null,"facebook":null,"meta_title":null,"meta_description":null,"coverImageSharp":null,"profileImageSharp":{"base":"IMG_0591.jpg","publicURL":"/static/ceb49c3c631485453e71e00d7f84b069/IMG_0591.jpg","imageMeta":{"width":1182,"height":1179},"childImageSharp":{"fluid":{"base64":"data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAUABQDASIAAhEBAxEB/8QAGAABAQEBAQAAAAAAAAAAAAAAAAMEAQL/xAAWAQEBAQAAAAAAAAAAAAAAAAADBAL/2gAMAwEAAhADEAAAAdXiFM6i0CohUWXoKn//xAAcEAACAgIDAAAAAAAAAAAAAAACAwESBBEhM0H/2gAIAQEAAQUCWySE3WEr7SzbXjAj4iKty+sOQ//EABYRAQEBAAAAAAAAAAAAAAAAAAERIP/aAAgBAwEBPwEhj//EABQRAQAAAAAAAAAAAAAAAAAAACD/2gAIAQIBAT8BH//EAB4QAAIBBAMBAAAAAAAAAAAAAAABIRESMUECECJx/9oACAEBAAY/ApVGWvOjzgtUwLlTZA0sdL4f/8QAHBAAAwACAwEAAAAAAAAAAAAAAAERITFBkbHB/9oACAEBAAE/IahkCy+N2GwZpjQiJHJCspUFY0QrSi+HqiW2rgf/2gAMAwEAAgADAAAAEPw3/wD/xAAYEQEBAAMAAAAAAAAAAAAAAAAAARExQf/aAAgBAwEBPxCtjDqP/8QAFxEBAQEBAAAAAAAAAAAAAAAAAQAxEf/aAAgBAgEBPxBFus6Tt//EAB8QAQEAAgIBBQAAAAAAAAAAAAERACExQWFRcYGR0f/aAAgBAQABPxAuaBPPzkO1wyX7F4wkwXanfZrFQgeqE9JgS14vVOvrERIJomVBKwt2jebAeP0yVa8h1n//2Q==","aspectRatio":1,"src":"/static/ceb49c3c631485453e71e00d7f84b069/31709/IMG_0591.jpg","srcSet":"/static/ceb49c3c631485453e71e00d7f84b069/f340b/IMG_0591.jpg 28w,\n/static/ceb49c3c631485453e71e00d7f84b069/22d64/IMG_0591.jpg 55w,\n/static/ceb49c3c631485453e71e00d7f84b069/31709/IMG_0591.jpg 110w,\n/static/ceb49c3c631485453e71e00d7f84b069/aa249/IMG_0591.jpg 165w,\n/static/ceb49c3c631485453e71e00d7f84b069/0dc33/IMG_0591.jpg 220w,\n/static/ceb49c3c631485453e71e00d7f84b069/d8257/IMG_0591.jpg 1182w","srcWebp":"/static/ceb49c3c631485453e71e00d7f84b069/8678c/IMG_0591.webp","srcSetWebp":"/static/ceb49c3c631485453e71e00d7f84b069/59cda/IMG_0591.webp 28w,\n/static/ceb49c3c631485453e71e00d7f84b069/7da75/IMG_0591.webp 55w,\n/static/ceb49c3c631485453e71e00d7f84b069/8678c/IMG_0591.webp 110w,\n/static/ceb49c3c631485453e71e00d7f84b069/f282e/IMG_0591.webp 165w,\n/static/ceb49c3c631485453e71e00d7f84b069/a7b21/IMG_0591.webp 220w,\n/static/ceb49c3c631485453e71e00d7f84b069/63099/IMG_0591.webp 1182w","sizes":"(max-width: 110px) 100vw, 110px"}}}},"primary_tag":{"slug":"reviews","url":"https://backend.shahednasser.com/tag/reviews/","name":"Reviews","visibility":"public","feature_image":"https://backend.shahednasser.com/content/images/2022/01/pexels-jess-bailey-designs-2647794--1--2.jpg","description":"Reviews for some services, products, or companies. If interested in having your product or service reviewed, please check out the \"collaborate\" page.","meta_title":null,"meta_description":null,"featureImageSharp":{"base":"pexels-jess-bailey-designs-2647794--1--2.jpg","publicURL":"/static/9dbdb73d894862ceac3b9ca3d26610aa/pexels-jess-bailey-designs-2647794--1--2.jpg","imageMeta":{"width":3456,"height":4608},"childImageSharp":{"fluid":{"base64":"data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAbABQDASIAAhEBAxEB/8QAGAAAAwEBAAAAAAAAAAAAAAAAAAEDAgX/xAAVAQEBAAAAAAAAAAAAAAAAAAAAAf/aAAwDAQACEAMQAAAB7zy0ACNJ1GYD/8QAGRAAAgMBAAAAAAAAAAAAAAAAAhABAxEg/9oACAEBAAEFAnuMaxjr/8QAFBEBAAAAAAAAAAAAAAAAAAAAIP/aAAgBAwEBPwEf/8QAFBEBAAAAAAAAAAAAAAAAAAAAIP/aAAgBAgEBPwEf/8QAGRAAAgMBAAAAAAAAAAAAAAAAARARITFR/9oACAEBAAY/AnbnT0sP/8QAGhABAAIDAQAAAAAAAAAAAAAAARARACFxUf/aAAgBAQABPyGUG0HZRtfoXhvcLfc//9oADAMBAAIAAwAAABCf5s7/xAAVEQEBAAAAAAAAAAAAAAAAAAAREP/aAAgBAwEBPxAiz//EABURAQEAAAAAAAAAAAAAAAAAABAR/9oACAECAQE/ECQ//8QAHhABAAICAgMBAAAAAAAAAAAAAQARECFBUTFhocH/2gAIAQEAAT8QMVK4XtVBEsxoUO0++I1cTg/ZcQFdLfvV4Vuf/9k=","aspectRatio":0.7492795389048992,"src":"/static/9dbdb73d894862ceac3b9ca3d26610aa/d5c54/pexels-jess-bailey-designs-2647794--1--2.jpg","srcSet":"/static/9dbdb73d894862ceac3b9ca3d26610aa/65d8c/pexels-jess-bailey-designs-2647794--1--2.jpg 260w,\n/static/9dbdb73d894862ceac3b9ca3d26610aa/c5f21/pexels-jess-bailey-designs-2647794--1--2.jpg 520w,\n/static/9dbdb73d894862ceac3b9ca3d26610aa/d5c54/pexels-jess-bailey-designs-2647794--1--2.jpg 1040w,\n/static/9dbdb73d894862ceac3b9ca3d26610aa/81a53/pexels-jess-bailey-designs-2647794--1--2.jpg 1560w,\n/static/9dbdb73d894862ceac3b9ca3d26610aa/f734f/pexels-jess-bailey-designs-2647794--1--2.jpg 2080w,\n/static/9dbdb73d894862ceac3b9ca3d26610aa/f2665/pexels-jess-bailey-designs-2647794--1--2.jpg 3456w","srcWebp":"/static/9dbdb73d894862ceac3b9ca3d26610aa/e4875/pexels-jess-bailey-designs-2647794--1--2.webp","srcSetWebp":"/static/9dbdb73d894862ceac3b9ca3d26610aa/dc8f3/pexels-jess-bailey-designs-2647794--1--2.webp 260w,\n/static/9dbdb73d894862ceac3b9ca3d26610aa/2db4b/pexels-jess-bailey-designs-2647794--1--2.webp 520w,\n/static/9dbdb73d894862ceac3b9ca3d26610aa/e4875/pexels-jess-bailey-designs-2647794--1--2.webp 1040w,\n/static/9dbdb73d894862ceac3b9ca3d26610aa/f5845/pexels-jess-bailey-designs-2647794--1--2.webp 1560w,\n/static/9dbdb73d894862ceac3b9ca3d26610aa/ecdd3/pexels-jess-bailey-designs-2647794--1--2.webp 2080w,\n/static/9dbdb73d894862ceac3b9ca3d26610aa/63d3e/pexels-jess-bailey-designs-2647794--1--2.webp 3456w","sizes":"(max-width: 1040px) 100vw, 1040px"}}}},"tags":[{"slug":"reviews","url":"https://backend.shahednasser.com/tag/reviews/","name":"Reviews","visibility":"public","feature_image":"https://backend.shahednasser.com/content/images/2022/01/pexels-jess-bailey-designs-2647794--1--2.jpg","description":"Reviews for some services, products, or companies. If interested in having your product or service reviewed, please check out the \"collaborate\" page.","meta_title":null,"meta_description":null,"featureImageSharp":null},{"slug":"react","url":"https://backend.shahednasser.com/tag/react/","name":"React","visibility":"public","feature_image":"https://images.unsplash.com/photo-1581276879432-15e50529f34b?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=MnwxMTc3M3wwfDF8c2VhcmNofDN8fHJlYWN0fGVufDB8fHx8MTYyMjYzMzI0MA&ixlib=rb-1.2.1&q=80&w=2000","description":"Learn more about React through tutorials, articles, and tips.","meta_title":null,"meta_description":null,"featureImageSharp":null},{"slug":"js","url":"https://backend.shahednasser.com/tag/js/","name":"Javascript","visibility":"public","feature_image":"https://backend.shahednasser.com/content/images/2022/01/photo-1592609931095-54a2168ae893-2.jpeg","description":"Learn more about Javascript through tutorials, articles, and tips.","meta_title":null,"meta_description":"Learn more about Javascript through tutorials, articles and tips.","featureImageSharp":null}],"plaintext":"React is one of the most popular JavaScript frontend frameworks. It allows you\nto create responsive, reactive, and blazingly fast websites and apps. You can\ncreate almost any type of website with React.\n\nOne issue that you’ll run into when you create a React app is internationalizing\nit. Internationalization (or i18n) is adding support for multiple languages to\nyour website. The process includes both translating the content as well as\nmodifying the style to support the language’s direction.\n\nThere are many solutions out there, and in a previous tutorial, I went through\nhow you can internationalize a React app using i18next\n[https://blog.shahednasser.com/how-to-internationalize-a-react-app/https://blog.shahednasser.com/how-to-internationalize-a-react-app/]\n. i18next [https://www.i18next.com/] is an open-source internationalization\nsolution that allows you to internationalize a lot of types of projects,\nincluding a React app.\n\nAnother internationalization solution for React is Transifex Native\n[https://www.transifex.com/native/]. Transifex is a localization platform that\nmakes internationalizing your projects, including your React project, much\neasier. Transifex bridges the gap between developers and translators, as it\nallows you to focus on the programming part while also working with translators\nto translate your website even if they’re not tech-savvy.\n\nIn this article, you’ll learn how to internationalize a React app using\nTransifex Native. I’ll be creating a website that’s exactly similar to the one I\ncreated in my tutorial for internationalization with i18next. This will allow\nyou to see the comparison between the two more clearly and see which is a better\noption.\n\nYou can find the code for this tutorial on this GitHub repository\n[https://github.com/shahednasser/react-transifex-tutorial].\n\nCreate a Transifex Account\nThe first step that you should take is to create a Transifex account\n[https://www.transifex.com/signup/]. Transifex has a 15-day free trial and a\nfree-forever plan for open-source projects!\n\nAfter you create an account, you’ll be asked to create a project. You’ll need to\nenter a project name. Then, for project type choose “Native”. Finally, you need\nto enter the main language of your website and what language(s) you’ll be\ntranslating your website to. In my case, I’ll choose English as the main\nlanguage and Arabic as the target language.\n\nOnce you’re done, click on Create Project.\n\nOn the next page, you’ll see instructions on how to create credentials for your\nproject. Click on Generate Native Credentials Now at the bottom of the page.\n\nThis will open a pop-up where you can see the API token and secret. Make sure to\ncopy both the keys as you’ll need them later.\n\nOnce that is done, you can start creating your React app and internationalizing\nit!\n\nCreate React App\nIn your terminal, run the following command:\n\n\nnpx create-react-app transifex-i18n\n\n\nThis will create the directory transifex-i18n with the React app inside. Change\nto that directory:\n\n\ncd transifex-i18n\n\n\nInstall Dependencies\nNow, you’ll install the dependencies that you’ll need for this tutorial. First,\ninstall React Bootstrap [https://react-bootstrap.github.io/] for easy styling:\n\n\nnpm install react-bootstrap@next bootstrap@5.1.0\n\n\nThen, install Transifex Native’s libraries that are essential for\ninternationalizing a React app:\n\n\nnpm install --save @transifex/native @transifex/react @transifex/cli\n\n\n@transifex/native is the core Transifex Native library. @transifex/react is the\nReact SDK that you can use in React projects. It provides an easy and\nReact-compatible interface for the core library. @transifex/cli is a CLI tool\nthat you’ll use to sync translatable strings between your codebase and your\nTransifex Native project.\n\nCreate Components\nYou’ll now create some components that you’ll use for your website.\n\nCreate src/components/Greeting.js with the following content:\n\n\nfunction Greeting () {\n  return (\n    <h1>\n      Hello\n    </h1>\n  );\n}\nexport default Greeting;\n\n\nCreate src/components/Text.js with the following content:\n\n\nfunction Text () {\n  return (\n    <p>\n      Thank you for visiting our website.\n    </p>\n  )\n}\nexport default Text;\n\n\nCreate src/components/Navigation.js with the following content:\n\nimport { Container, Nav, Navbar, NavDropdown } from \"react-bootstrap\";\n\n\nimport { Container, Nav, Navbar, NavDropdown } from \"react-bootstrap\";\n\nfunction Navigation () {\n\n  return (\n    <Navbar bg=\"light\" expand=\"lg\">\n      <Container>\n        <Navbar.Brand href=\"#\">Transifex React Internationalization</Navbar.Brand>\n        <Navbar.Toggle aria-controls=\"basic-navbar-nav\" />\n        <Navbar.Collapse id=\"basic-navbar-nav\">\n          <Nav className=\"ms-auto\">\n            <NavDropdown title=\"Language\" id=\"basic-nav-dropdown\">\n              <NavDropdown.Item href=\"#\">English</NavDropdown.Item>\n              <NavDropdown.Item href=\"#\">Arabic</NavDropdown.Item>\n            </NavDropdown>\n          </Nav>\n        </Navbar.Collapse>\n      </Container>\n    </Navbar>\n  );\n}\nexport default Navigation;\n\n\nFinally, replace the content of src/App.js with the following:\n\nimport React from 'react';\nimport { Container } from 'react-bootstrap';\nimport 'bootstrap/dist/css/bootstrap.min.css';\nimport Greeting from './components/Greeting';\nimport Navigation from './components/Navigation';\nimport Text from './components/Text';\n\nfunction App() {\n\n  return (\n    <>\n      <Navigation />\n      <Container>\n        <Greeting />\n        <Text />\n      </Container>\n    </>\n  );\n}\nexport default App;\n\n\nRun the Website\nIn your terminal, run the following command to run the website:\n\nnpm start\n\n\nThis will open the website in your browser and you can see all the components\nyou just created.\n\nLocalize Website\nAt the moment, the website is all in English and you can’t switch between\nlanguages or see any translations. You’ll now localize the website using your\nTransifex account.\n\nInitialize Transifex\nThe first step is to initialize Transifex Native on the website. To do that, add\nthe following import in src/App.js:\n\nimport { tx } from '@transifex/native';\n\n\nThen, before the function App add the following code to initialize Transifex\nNative:\n\ntx.init({\n  token: process.env.REACT_APP_TRANSIFEX_TOKEN,\n});\n\n\nAs you can see, you can use the init method of tx that is imported from the core\nTransifex Native library. You need to pass it the token that you copied earlier\nfrom your Transifex Native credentials. We pass it as a React environment\nvariable\n[https://create-react-app.dev/docs/adding-custom-environment-variables/].\n\nTo add the environment variable, create .env in the root of your React app with\nthe following:\n\nREACT_APP_TRANSIFEX_TOKEN=\n\n\nWhere the value is the API token that you copied earlier.\n\nAdd Translatable Strings\nNow, you can make any string translatable. To do that, the Transifex Native\nReact SDK has a component T that you can use to indicate that a text is\ntranslatable.\n\nOpen src/components/Greeting.js and add the import for T at the beginning of the\nfile:\n\nimport { T } from '@transifex/react';\n\n\nThen, replace “Hello” with the following:\n\n<T _str=\"Hello\" />\n\n\nAs you can see, the component T accepts a prop _str with the text that can be\ntranslated.\n\nT can also accept the following props:\n\n 1. _context: The context of the string.\n 2. _key: custom key string\n 3. _comment: comments from the developer about the string\n 4. _charlimit: set a character limit for the translator to adhere to\n 5. _tags: tags separated by commas\n\nSimilarly, open src/components/Text.js and add the following import at the\nbeginning of the file:\n\nimport { T } from '@transifex/react';\n\n\nThen, replace \"Thank you for visiting our website.\" with the following:\n\n<T _str=\"Thank you for visiting our website.\" />\n\n\nPush Translation Strings\nYou just added 2 translatable strings. The next step is to push these strings to\nyour Transifex Native project so they can be viewed on the project dashboard.\n\nIn package.json add the following new script:\n\n\"scripts\": {\n  ...,\n  \"push-translation\": \"txjs-cli push src --token=<TOKEN> --secret=<SECRET>\"\n}\n\n\nMake sure to replace the <TOKEN> with your API token and <SECRET> with your API\nsecret.\n\nUsing the CLI library that you installed earlier you can push translations to\nthe Transifex Native project using the push command. The push command takes the\ndirectory it should look inside for translatable strings as a parameter. It also\nneeds the token and secret you copied earlier.\n\nNow, in your terminal, run the following command:\n\nnpm run push-translation\n\n\nAfter this is run successfully, you’ll see that 2 string resources have been\ncreated. If you open the Resources page on your Transifex Native project, you\nshould see that there are 2 strings that need a translation.\n\nIf you click on the Translate button at the top right, you’ll be taken into a\nnew page where you can select the language to translate the strings to. Select\nthe language you want, and then you’ll be able to add the translations for each\nstring using the easy-to-use interface.\n\nChange Languages\nOk, so, now you added the translations, but you need to be able to switch\nbetween languages on your website to see this change in action.\n\nThe Transifex Native React SDK has the hook useLanguages that allows you to\nretrieve the available languages in your project. You can use that to display\nthe languages and allow the user to switch between them. To change languages,\nyou can use the setCurrentLocale method from the core native library.\n\nAlternatively, you can use the \n[LanguagePicker](https://docs.transifex.com/javascript-sdk/localize-react-applications#languagepicker-component) \n component\n[https://docs.transifex.com/javascript-sdk/localize-react-applications#languagepicker-component] \nfrom the same SDK that provides the entire UI and functionality ready for you.\nHowever, you will not have the ability to customize the UI.\n\nOpen src/components/Navigation.js and add the following imports at the beginning\nof the file:\n\nimport { tx } from '@transifex/native';\nimport { useLanguages } from '@transifex/react';\n\n\nThen, inside the Navigation function create a new languages variable:\n\nconst languages = useLanguages();\n\n\nThen, replace the elements nested inside NavDropdown with the following:\n\n{languages.map(({code, name}) => (\n  <NavDropdown.Item key={code} href=\"#\" onClick={() => tx.setCurrentLocale(code)}>{name}</NavDropdown.Item>\n))}\n\n\nThis will loop over the languages variable. Each language inside it will have \ncode and name attributes. You use that to display each language as a dropdown\nitem in the navigation bar. When the item is clicked, the language will be\nchanged to the clicked language using tx.setCurrentLocale, which accepts the\nlanguage code (or locale) as a parameter.\n\nIf you open your website now, you should see the languages when you click on the\nLanguages dropdown.\n\nTry clicking on the second language, which in my case is Arabic. You’ll see that\nall the strings will be translated as you translated them in your Transifex\nNative project dashboard.\n\nTranslating More Text\nLet’s now translate the “Language” string in the Navigation component.\n\nIn src/components/Navigation.js file add the import for T:\n\nimport { T, useLanguages } from '@transifex/react';\n\n\nThen, change the title prop of NavDropdown to the following:\n\ntitle={<T _str=\"Language\" />}\n\n\nThe title prop can accept a component as a value.\n\nYou’ll need to push the new string to the Transifex Native project so run the \npush-translation command again:\n\nnpm run push-translation\n\n\nThis will push all new strings and skip already-created strings. If you open\nyour project dashboard now you should see a new string “Language” added there.\n\nGo ahead and translate the string, then run the website again. You might see\nthat the “Language” string isn’t translated right away when you switch\nlanguages. That’s because Transifex Native caches your translations.\n\nTo invalidate the cache, you can use the invalidate command of the CLI tool.\n\nIn package.json add the new script refresh-translation and make changes to the \nstart script so that the translations are refreshed whenever the server for your\nwebsite is started:\n\n\"scripts\": {\n    \"start\": \"npm run refresh-translation && react-scripts start\",\n    ...,\n    \"refresh-translation\": \"txjs-cli invalidate --token=<TOKEN> --secret=<SECRET>\"\n  },\n\n\nJust like before, make sure to replace <TOKEN> and <SECRET> with your\ncredentials.\n\nNow, run the start command again or run the refresh-translationcommand on its\nown. The “Language” string should now be translated when you switch languages.\n\nChanging Layout\nThe next part of internationalization is making sure that the layout conforms\nwith the selected language’s directionality. As Arabic is a right-to-left (RTL)\nlanguage, the layout needs to be flipped when the Arabic language is chosen.\n\nThe Transifex Native React SDK has a useLocale hook that you can use to retrieve\nthe current chosen locale. We’ll use that to change the document direction and\nmake any necessary changes based on the current language.\n\nIn src/App.js add imports at the beginning of the file:\n\nimport React, { useEffect } from 'react';\nimport { useLocale } from '@transifex/react';\n\n\nThen, inside the App function, add the following before the returnstatement:\n\nconst locale = useLocale();\nuseEffect(() => {\n  if (locale) {\n    document.body.style.direction = locale === 'en' ? 'ltr' : 'rtl';\n  }\n}, [locale]);\n\n\nYou first retrieve the locale using useLocale. Then, whenever locale is changed,\nyou change the direction style property of the body of the page based on the\nlocale.\n\nNext, in src/components/Navbar.js add the necessary import for useLocale:\n\nimport { T, useLanguages, useLocale } from '@transifex/react';\n\n\nThen, create the locale variable inside the Navigation function:\n\nconst locale = useLocale();\n\n\nFinally, change the className prop of the Nav element to the following:\n\nclassName={!locale || locale === 'en' ? \"ms-auto\" : \"me-auto\"}\n\n\nThis will make sure that when the language is English the “Language” dropdown\nwill appear at the right, otherwise, it will appear on the left.\n\nNow, open the website and switch to an RTL language. You should see that the\nlayout has changed.\n\nIf you try to switch back to English, the layout will go back to the way it was.\n\nBenefits of Transifex Native React SDK\nIf you went through the previous i18next tutorial, or you already know how\ni18next works, and you went through this tutorial, you can easily spot all the\nbenefits of the Transifex Native React SDK.\n\nThe main benefit of using Transifex Native is that the translations are not part\nof your codebase. For bigger projects or projects that require translators that\naren’t tech-savvy, this makes it much easier to translate a website, as the\ntranslation can all happen from the dashboard. Developers can then just focus on\ndeveloping the website as necessary.\n\nThis is also very beneficial for projects that include multiple environments. If\nyou have a website, an iOS app, and an Android app, it’s a hassle to\ninternationalize all these different projects as they each have a different way\nof translating string resources. As Transifex has SDKs for all these types of\nprojects\n[https://docs.transifex.com/getting-started-with-native/getting-started-with-transifex-native]\n, and as it also has REST APIs [https://transifex.github.io/openapi/index.html] \nthat allow you to access your project resources from basically anywhere, all you\nneed is to translate these strings on the Transifex Native project dashboard and\nany component of your application can have access to them.\n\nAnother benefit of using Transifex’s SDKs is how easy it is to retrieve\nlanguages and currently selected locales. When I used i18next in the previous\ntutorial, retrieving the current locale had to be done through React Context\n[https://reactjs.org/docs/context.html]. This concept can seem complex to some,\nso to be able to easily retrieve the current locale is also a nice plus.\n\nThe Transifex Native React SDK adds an easy interface and components that you\ncan use in your code to remove all the hassles that might come with\ninternationalization. This is a big plus for the developer experience.\n\nConclusion\nTransifex is the perfect platform for internationalizing a lot of types of\nprojects, especially React apps. With Transifex Native, you can use the React\nSDK to add strings to be translated, get languages, get current locale, and\nmore. You can then easily translate the strings from the dashboard and access\nthem whenever.\n\nI found Transifex Native very easy to use as a developer. Its process allows you\nto stay efficient and focused on the programming part. When it comes to\nlocalization and translating your content, you’ll most likely need the help of\nother team members, and there’s a chance they won’t know how to do it through\nediting the source code. This is something that you can solve with Transifex\n[https://www.transifex.com/blog/2021/react-i18n-data-backed-benefits-of-transifex-native/]\n. You can also crowdsource\n[https://docs.transifex.com/localization-tips-workflows/crowdsourcing-translations] \nyour translation if you have an open-source project and need the help of the\ncommunity.\n\nBe sure to check out Transifex’s React SDK documentation\n[https://docs.transifex.com/javascript-sdk/localize-react-applications] to see\nall the functionalities it provides and see all the cool things you can do with\nthis SDK and platform as a whole.","html":"<p>React is one of the most popular JavaScript frontend frameworks. It allows you to create responsive, reactive, and blazingly fast websites and apps. You can create almost any type of website with React.</p><p>One issue that you’ll run into when you create a React app is internationalizing it. Internationalization (or i18n) is adding support for multiple languages to your website. The process includes both translating the content as well as modifying the style to support the language’s direction.</p><p>There are many solutions out there, and in a previous tutorial, I went through how you can <a href=\"https://blog.shahednasser.com/how-to-internationalize-a-react-app/https://blog.shahednasser.com/how-to-internationalize-a-react-app/\">internationalize a React app using i18next</a>. <a href=\"https://www.i18next.com/\">i18next</a> is an open-source internationalization solution that allows you to internationalize a lot of types of projects, including a React app.</p><p>Another internationalization solution for React is <a href=\"https://www.transifex.com/native/\">Transifex Native</a>. Transifex is a localization platform that makes internationalizing your projects, including your React project, much easier. Transifex bridges the gap between developers and translators, as it allows you to focus on the programming part while also working with translators to translate your website even if they’re not tech-savvy.</p><p>In this article, you’ll learn how to internationalize a React app using Transifex Native. I’ll be creating a website that’s exactly similar to the one I created in my tutorial for internationalization with i18next. This will allow you to see the comparison between the two more clearly and see which is a better option.</p><p>You can find the code for this tutorial on <a href=\"https://github.com/shahednasser/react-transifex-tutorial\">this GitHub repository</a>.</p><h1 id=\"create-a-transifex-account\">Create a Transifex Account</h1><p>The first step that you should take is to <a href=\"https://www.transifex.com/signup/\">create a Transifex account</a>. Transifex has a 15-day free trial and a free-forever plan for open-source projects!</p><p>After you create an account, you’ll be asked to create a project. You’ll need to enter a project name. Then, for project type choose “Native”. Finally, you need to enter the main language of your website and what language(s) you’ll be translating your website to. In my case, I’ll choose English as the main language and Arabic as the target language.</p><figure class=\"kg-card kg-image-card\"><img src=\"https://backend.shahednasser.com/content/images/2022/01/Screen-Shot-2022-01-19-at-11.09.13-AM.png\" class=\"kg-image\" alt loading=\"lazy\" width=\"2000\" height=\"1080\" srcset=\"https://backend.shahednasser.com/content/images/size/w600/2022/01/Screen-Shot-2022-01-19-at-11.09.13-AM.png 600w, https://backend.shahednasser.com/content/images/size/w1000/2022/01/Screen-Shot-2022-01-19-at-11.09.13-AM.png 1000w, https://backend.shahednasser.com/content/images/size/w1600/2022/01/Screen-Shot-2022-01-19-at-11.09.13-AM.png 1600w, https://backend.shahednasser.com/content/images/size/w2400/2022/01/Screen-Shot-2022-01-19-at-11.09.13-AM.png 2400w\" sizes=\"(min-width: 720px) 720px\"></figure><p>Once you’re done, click on <em>Create Project</em>.</p><p>On the next page, you’ll see instructions on how to create credentials for your project. Click on <em>Generate Native Credentials Now</em> at the bottom of the page.</p><figure class=\"kg-card kg-image-card\"><img src=\"https://backend.shahednasser.com/content/images/2022/01/Screen-Shot-2022-01-19-at-11.41.08-AM.png\" class=\"kg-image\" alt loading=\"lazy\" width=\"2000\" height=\"1160\" srcset=\"https://backend.shahednasser.com/content/images/size/w600/2022/01/Screen-Shot-2022-01-19-at-11.41.08-AM.png 600w, https://backend.shahednasser.com/content/images/size/w1000/2022/01/Screen-Shot-2022-01-19-at-11.41.08-AM.png 1000w, https://backend.shahednasser.com/content/images/size/w1600/2022/01/Screen-Shot-2022-01-19-at-11.41.08-AM.png 1600w, https://backend.shahednasser.com/content/images/2022/01/Screen-Shot-2022-01-19-at-11.41.08-AM.png 2018w\" sizes=\"(min-width: 720px) 720px\"></figure><p>This will open a pop-up where you can see the API token and secret. Make sure to copy both the keys as you’ll need them later.</p><p>Once that is done, you can start creating your React app and internationalizing it!</p><h1 id=\"create-react-app\">Create React App</h1><p>In your terminal, run the following command:<br></p><pre><code>npx create-react-app transifex-i18n\n</code></pre><p>This will create the directory <code>transifex-i18n</code> with the React app inside. Change to that directory:<br></p><pre><code>cd transifex-i18n\n</code></pre><h1 id=\"install-dependencies\">Install Dependencies</h1><p>Now, you’ll install the dependencies that you’ll need for this tutorial. First, install <a href=\"https://react-bootstrap.github.io/\">React Bootstrap</a> for easy styling:<br></p><pre><code>npm install react-bootstrap@next bootstrap@5.1.0\n</code></pre><p>Then, install Transifex Native’s libraries that are essential for internationalizing a React app:<br></p><pre><code>npm install --save @transifex/native @transifex/react @transifex/cli\n</code></pre><p><code>@transifex/native</code> is the core Transifex Native library. <code>@transifex/react</code> is the React SDK that you can use in React projects. It provides an easy and React-compatible interface for the core library. <code>@transifex/cli</code> is a CLI tool that you’ll use to sync translatable strings between your codebase and your Transifex Native project.</p><h1 id=\"create-components\">Create Components</h1><p>You’ll now create some components that you’ll use for your website.</p><p>Create <code>src/components/Greeting.js</code> with the following content:<br></p><pre><code>function Greeting () {\n  return (\n    &lt;h1&gt;\n      Hello\n    &lt;/h1&gt;\n  );\n}\nexport default Greeting;\n</code></pre><p>Create <code>src/components/Text.js</code> with the following content:<br></p><pre><code>function Text () {\n  return (\n    &lt;p&gt;\n      Thank you for visiting our website.\n    &lt;/p&gt;\n  )\n}\nexport default Text;\n</code></pre><p>Create <code>src/components/Navigation.js</code> with the following content:</p><pre><code>import { Container, Nav, Navbar, NavDropdown } from \"react-bootstrap\";\n</code></pre><pre><code>import { Container, Nav, Navbar, NavDropdown } from \"react-bootstrap\";\n\nfunction Navigation () {\n\n  return (\n    &lt;Navbar bg=\"light\" expand=\"lg\"&gt;\n      &lt;Container&gt;\n        &lt;Navbar.Brand href=\"#\"&gt;Transifex React Internationalization&lt;/Navbar.Brand&gt;\n        &lt;Navbar.Toggle aria-controls=\"basic-navbar-nav\" /&gt;\n        &lt;Navbar.Collapse id=\"basic-navbar-nav\"&gt;\n          &lt;Nav className=\"ms-auto\"&gt;\n            &lt;NavDropdown title=\"Language\" id=\"basic-nav-dropdown\"&gt;\n              &lt;NavDropdown.Item href=\"#\"&gt;English&lt;/NavDropdown.Item&gt;\n              &lt;NavDropdown.Item href=\"#\"&gt;Arabic&lt;/NavDropdown.Item&gt;\n            &lt;/NavDropdown&gt;\n          &lt;/Nav&gt;\n        &lt;/Navbar.Collapse&gt;\n      &lt;/Container&gt;\n    &lt;/Navbar&gt;\n  );\n}\nexport default Navigation;\n</code></pre><p>Finally, replace the content of <code>src/App.js</code> with the following:</p><pre><code>import React from 'react';\nimport { Container } from 'react-bootstrap';\nimport 'bootstrap/dist/css/bootstrap.min.css';\nimport Greeting from './components/Greeting';\nimport Navigation from './components/Navigation';\nimport Text from './components/Text';\n\nfunction App() {\n\n  return (\n    &lt;&gt;\n      &lt;Navigation /&gt;\n      &lt;Container&gt;\n        &lt;Greeting /&gt;\n        &lt;Text /&gt;\n      &lt;/Container&gt;\n    &lt;/&gt;\n  );\n}\nexport default App;\n</code></pre><h1 id=\"run-the-website\">Run the Website</h1><p>In your terminal, run the following command to run the website:</p><pre><code>npm start\n</code></pre><p>This will open the website in your browser and you can see all the components you just created.</p><figure class=\"kg-card kg-image-card\"><img src=\"https://backend.shahednasser.com/content/images/2022/01/Screen-Shot-2022-01-20-at-10.58.05-AM.png\" class=\"kg-image\" alt loading=\"lazy\" width=\"2000\" height=\"300\" srcset=\"https://backend.shahednasser.com/content/images/size/w600/2022/01/Screen-Shot-2022-01-20-at-10.58.05-AM.png 600w, https://backend.shahednasser.com/content/images/size/w1000/2022/01/Screen-Shot-2022-01-20-at-10.58.05-AM.png 1000w, https://backend.shahednasser.com/content/images/size/w1600/2022/01/Screen-Shot-2022-01-20-at-10.58.05-AM.png 1600w, https://backend.shahednasser.com/content/images/2022/01/Screen-Shot-2022-01-20-at-10.58.05-AM.png 2310w\" sizes=\"(min-width: 720px) 720px\"></figure><h1 id=\"localize-website\">Localize Website</h1><p>At the moment, the website is all in English and you can’t switch between languages or see any translations. You’ll now localize the website using your Transifex account.</p><h2 id=\"initialize-transifex\">Initialize Transifex</h2><p>The first step is to initialize Transifex Native on the website. To do that, add the following import in <code>src/App.js</code>:</p><pre><code>import { tx } from '@transifex/native';\n</code></pre><p>Then, before the function <code>App</code> add the following code to initialize Transifex Native:</p><pre><code>tx.init({\n  token: process.env.REACT_APP_TRANSIFEX_TOKEN,\n});\n</code></pre><p>As you can see, you can use the <code>init</code> method of <code>tx</code> that is imported from the core Transifex Native library. You need to pass it the token that you copied earlier from your Transifex Native credentials. We pass it as a <a href=\"https://create-react-app.dev/docs/adding-custom-environment-variables/\">React environment variable</a>.</p><p>To add the environment variable, create <code>.env</code> in the root of your React app with the following:</p><pre><code>REACT_APP_TRANSIFEX_TOKEN=\n</code></pre><p>Where the value is the API token that you copied earlier.</p><h2 id=\"add-translatable-strings\">Add Translatable Strings</h2><p>Now, you can make any string translatable. To do that, the Transifex Native React SDK has a component <code>T</code> that you can use to indicate that a text is translatable.</p><p>Open <code>src/components/Greeting.js</code> and add the import for <code>T</code> at the beginning of the file:</p><pre><code>import { T } from '@transifex/react';\n</code></pre><p>Then, replace “Hello” with the following:</p><pre><code>&lt;T _str=\"Hello\" /&gt;\n</code></pre><p>As you can see, the component <code>T</code> accepts a prop <code>_str</code> with the text that can be translated.</p><p><code>T</code> can also accept the following props:</p><ol><li><code>_context</code>: The context of the string.</li><li><code>_key</code>: custom key string</li><li><code>_comment</code>: comments from the developer about the string</li><li><code>_charlimit</code>: set a character limit for the translator to adhere to</li><li><code>_tags</code>: tags separated by commas</li></ol><p>Similarly, open <code>src/components/Text.js</code> and add the following import at the beginning of the file:</p><pre><code>import { T } from '@transifex/react';\n</code></pre><p>Then, replace <code>\"Thank you for visiting our website.\"</code> with the following:</p><pre><code>&lt;T _str=\"Thank you for visiting our website.\" /&gt;\n</code></pre><h2 id=\"push-translation-strings\">Push Translation Strings</h2><p>You just added 2 translatable strings. The next step is to push these strings to your Transifex Native project so they can be viewed on the project dashboard.</p><p>In <code>package.json</code> add the following new script:</p><pre><code>\"scripts\": {\n  ...,\n  \"push-translation\": \"txjs-cli push src --token=&lt;TOKEN&gt; --secret=&lt;SECRET&gt;\"\n}\n</code></pre><p>Make sure to replace the <code>&lt;TOKEN&gt;</code> with your API token and <code>&lt;SECRET&gt;</code> with your API secret.</p><p>Using the CLI library that you installed earlier you can push translations to the Transifex Native project using the <code>push</code> command. The <code>push</code> command takes the directory it should look inside for translatable strings as a parameter. It also needs the token and secret you copied earlier.</p><p>Now, in your terminal, run the following command:</p><pre><code>npm run push-translation\n</code></pre><p>After this is run successfully, you’ll see that 2 string resources have been created. If you open the Resources page on your Transifex Native project, you should see that there are 2 strings that need a translation.</p><figure class=\"kg-card kg-image-card\"><img src=\"https://backend.shahednasser.com/content/images/2022/01/Screen-Shot-2022-01-19-at-11.51.16-AM.png\" class=\"kg-image\" alt loading=\"lazy\" width=\"2000\" height=\"423\" srcset=\"https://backend.shahednasser.com/content/images/size/w600/2022/01/Screen-Shot-2022-01-19-at-11.51.16-AM.png 600w, https://backend.shahednasser.com/content/images/size/w1000/2022/01/Screen-Shot-2022-01-19-at-11.51.16-AM.png 1000w, https://backend.shahednasser.com/content/images/size/w1600/2022/01/Screen-Shot-2022-01-19-at-11.51.16-AM.png 1600w, https://backend.shahednasser.com/content/images/2022/01/Screen-Shot-2022-01-19-at-11.51.16-AM.png 2006w\" sizes=\"(min-width: 720px) 720px\"></figure><p>If you click on the Translate button at the top right, you’ll be taken into a new page where you can select the language to translate the strings to. Select the language you want, and then you’ll be able to add the translations for each string using the easy-to-use interface.</p><figure class=\"kg-card kg-image-card\"><img src=\"https://backend.shahednasser.com/content/images/2022/01/Screen-Shot-2022-01-19-at-12.24.25-PM.png\" class=\"kg-image\" alt loading=\"lazy\" width=\"2000\" height=\"765\" srcset=\"https://backend.shahednasser.com/content/images/size/w600/2022/01/Screen-Shot-2022-01-19-at-12.24.25-PM.png 600w, https://backend.shahednasser.com/content/images/size/w1000/2022/01/Screen-Shot-2022-01-19-at-12.24.25-PM.png 1000w, https://backend.shahednasser.com/content/images/size/w1600/2022/01/Screen-Shot-2022-01-19-at-12.24.25-PM.png 1600w, https://backend.shahednasser.com/content/images/size/w2400/2022/01/Screen-Shot-2022-01-19-at-12.24.25-PM.png 2400w\" sizes=\"(min-width: 720px) 720px\"></figure><h2 id=\"change-languages\">Change Languages</h2><p>Ok, so, now you added the translations, but you need to be able to switch between languages on your website to see this change in action.</p><p>The Transifex Native React SDK has the hook <code>useLanguages</code> that allows you to retrieve the available languages in your project. You can use that to display the languages and allow the user to switch between them. To change languages, you can use the <code>setCurrentLocale</code> method from the core native library.</p><p>Alternatively, you can use the <code>[LanguagePicker](https://docs.transifex.com/javascript-sdk/localize-react-applications#languagepicker-component)</code> <a href=\"https://docs.transifex.com/javascript-sdk/localize-react-applications#languagepicker-component\">component</a> from the same SDK that provides the entire UI and functionality ready for you. However, you will not have the ability to customize the UI.</p><p>Open <code>src/components/Navigation.js</code> and add the following imports at the beginning of the file:</p><pre><code>import { tx } from '@transifex/native';\nimport { useLanguages } from '@transifex/react';\n</code></pre><p>Then, inside the <code>Navigation</code> function create a new <code>languages</code> variable:</p><pre><code>const languages = useLanguages();\n</code></pre><p>Then, replace the elements nested inside <code>NavDropdown</code> with the following:</p><pre><code>{languages.map(({code, name}) =&gt; (\n  &lt;NavDropdown.Item key={code} href=\"#\" onClick={() =&gt; tx.setCurrentLocale(code)}&gt;{name}&lt;/NavDropdown.Item&gt;\n))}\n</code></pre><p>This will loop over the <code>languages</code> variable. Each <code>language</code> inside it will have <code>code</code> and <code>name</code> attributes. You use that to display each language as a dropdown item in the navigation bar. When the item is clicked, the language will be changed to the clicked language using <code>tx.setCurrentLocale</code>, which accepts the language code (or locale) as a parameter.</p><p>If you open your website now, you should see the languages when you click on the Languages dropdown.</p><figure class=\"kg-card kg-image-card\"><img src=\"https://backend.shahednasser.com/content/images/2022/01/Screen-Shot-2022-01-20-at-11.31.39-AM.png\" class=\"kg-image\" alt loading=\"lazy\" width=\"378\" height=\"316\"></figure><p>Try clicking on the second language, which in my case is Arabic. You’ll see that all the strings will be translated as you translated them in your Transifex Native project dashboard.</p><figure class=\"kg-card kg-image-card\"><img src=\"https://backend.shahednasser.com/content/images/2022/01/Screen-Shot-2022-01-20-at-11.33.37-AM.png\" class=\"kg-image\" alt loading=\"lazy\" width=\"2000\" height=\"230\" srcset=\"https://backend.shahednasser.com/content/images/size/w600/2022/01/Screen-Shot-2022-01-20-at-11.33.37-AM.png 600w, https://backend.shahednasser.com/content/images/size/w1000/2022/01/Screen-Shot-2022-01-20-at-11.33.37-AM.png 1000w, https://backend.shahednasser.com/content/images/size/w1600/2022/01/Screen-Shot-2022-01-20-at-11.33.37-AM.png 1600w, https://backend.shahednasser.com/content/images/size/w2400/2022/01/Screen-Shot-2022-01-20-at-11.33.37-AM.png 2400w\" sizes=\"(min-width: 720px) 720px\"></figure><h2 id=\"translating-more-text\">Translating More Text</h2><p>Let’s now translate the “Language” string in the Navigation component.</p><p>In <code>src/components/Navigation.js</code> file add the import for <code>T</code>:</p><pre><code>import { T, useLanguages } from '@transifex/react';\n</code></pre><p>Then, change the <code>title</code> prop of <code>NavDropdown</code> to the following:</p><pre><code>title={&lt;T _str=\"Language\" /&gt;}\n</code></pre><p>The <code>title</code> prop can accept a component as a value.</p><p>You’ll need to push the new string to the Transifex Native project so run the <code>push-translation</code> command again:</p><pre><code>npm run push-translation\n</code></pre><p>This will push all new strings and skip already-created strings. If you open your project dashboard now you should see a new string “Language” added there.</p><p>Go ahead and translate the string, then run the website again. You might see that the “Language” string isn’t translated right away when you switch languages. That’s because Transifex Native caches your translations.</p><p>To invalidate the cache, you can use the <code>invalidate</code> command of the CLI tool.</p><p>In <code>package.json</code> add the new script <code>refresh-translation</code> and make changes to the <code>start</code> script so that the translations are refreshed whenever the server for your website is started:</p><pre><code>\"scripts\": {\n    \"start\": \"npm run refresh-translation &amp;&amp; react-scripts start\",\n    ...,\n    \"refresh-translation\": \"txjs-cli invalidate --token=&lt;TOKEN&gt; --secret=&lt;SECRET&gt;\"\n  },\n</code></pre><p>Just like before, make sure to replace <code>&lt;TOKEN&gt;</code> and <code>&lt;SECRET&gt;</code> with your credentials.</p><p>Now, run the <code>start</code> command again or run the <code>refresh-translation</code>command on its own. The “Language” string should now be translated when you switch languages.</p><figure class=\"kg-card kg-image-card\"><img src=\"https://backend.shahednasser.com/content/images/2022/01/Screen-Shot-2022-01-19-at-1.04.05-PM-1.png\" class=\"kg-image\" alt loading=\"lazy\" width=\"2000\" height=\"252\" srcset=\"https://backend.shahednasser.com/content/images/size/w600/2022/01/Screen-Shot-2022-01-19-at-1.04.05-PM-1.png 600w, https://backend.shahednasser.com/content/images/size/w1000/2022/01/Screen-Shot-2022-01-19-at-1.04.05-PM-1.png 1000w, https://backend.shahednasser.com/content/images/size/w1600/2022/01/Screen-Shot-2022-01-19-at-1.04.05-PM-1.png 1600w, https://backend.shahednasser.com/content/images/size/w2400/2022/01/Screen-Shot-2022-01-19-at-1.04.05-PM-1.png 2400w\" sizes=\"(min-width: 720px) 720px\"></figure><h1 id=\"changing-layout\">Changing Layout</h1><p>The next part of internationalization is making sure that the layout conforms with the selected language’s directionality. As Arabic is a right-to-left (RTL) language, the layout needs to be flipped when the Arabic language is chosen.</p><p>The Transifex Native React SDK has a <code>useLocale</code> hook that you can use to retrieve the current chosen locale. We’ll use that to change the document direction and make any necessary changes based on the current language.</p><p>In <code>src/App.js</code> add imports at the beginning of the file:</p><pre><code>import React, { useEffect } from 'react';\nimport { useLocale } from '@transifex/react';\n</code></pre><p>Then, inside the <code>App</code> function, add the following before the <code>return</code>statement:</p><pre><code>const locale = useLocale();\nuseEffect(() =&gt; {\n  if (locale) {\n    document.body.style.direction = locale === 'en' ? 'ltr' : 'rtl';\n  }\n}, [locale]);\n</code></pre><p>You first retrieve the locale using <code>useLocale</code>. Then, whenever <code>locale</code> is changed, you change the <code>direction</code> style property of the <code>body</code> of the page based on the locale.</p><p>Next, in <code>src/components/Navbar.js</code> add the necessary import for <code>useLocale</code>:</p><pre><code>import { T, useLanguages, useLocale } from '@transifex/react';\n</code></pre><p>Then, create the <code>locale</code> variable inside the <code>Navigation</code> function:</p><pre><code>const locale = useLocale();\n</code></pre><p>Finally, change the <code>className</code> prop of the <code>Nav</code> element to the following:</p><pre><code>className={!locale || locale === 'en' ? \"ms-auto\" : \"me-auto\"}\n</code></pre><p>This will make sure that when the language is English the “Language” dropdown will appear at the right, otherwise, it will appear on the left.</p><p>Now, open the website and switch to an RTL language. You should see that the layout has changed.</p><figure class=\"kg-card kg-image-card\"><img src=\"https://backend.shahednasser.com/content/images/2022/01/Screen-Shot-2022-01-19-at-1.06.24-PM.png\" class=\"kg-image\" alt loading=\"lazy\" width=\"2000\" height=\"329\" srcset=\"https://backend.shahednasser.com/content/images/size/w600/2022/01/Screen-Shot-2022-01-19-at-1.06.24-PM.png 600w, https://backend.shahednasser.com/content/images/size/w1000/2022/01/Screen-Shot-2022-01-19-at-1.06.24-PM.png 1000w, https://backend.shahednasser.com/content/images/size/w1600/2022/01/Screen-Shot-2022-01-19-at-1.06.24-PM.png 1600w, https://backend.shahednasser.com/content/images/size/w2400/2022/01/Screen-Shot-2022-01-19-at-1.06.24-PM.png 2400w\" sizes=\"(min-width: 720px) 720px\"></figure><p>If you try to switch back to English, the layout will go back to the way it was.</p><h1 id=\"benefits-of-transifex-native-react-sdk\">Benefits of Transifex Native React SDK</h1><p>If you went through the previous i18next tutorial, or you already know how i18next works, and you went through this tutorial, you can easily spot all the benefits of the Transifex Native React SDK.</p><p>The main benefit of using Transifex Native is that the translations are not part of your codebase. For bigger projects or projects that require translators that aren’t tech-savvy, this makes it much easier to translate a website, as the translation can all happen from the dashboard. Developers can then just focus on developing the website as necessary.</p><p>This is also very beneficial for projects that include multiple environments. If you have a website, an iOS app, and an Android app, it’s a hassle to internationalize all these different projects as they each have a different way of translating string resources. As Transifex has <a href=\"https://docs.transifex.com/getting-started-with-native/getting-started-with-transifex-native\">SDKs for all these types of projects</a>, and as it also has <a href=\"https://transifex.github.io/openapi/index.html\">REST APIs</a> that allow you to access your project resources from basically anywhere, all you need is to translate these strings on the Transifex Native project dashboard and any component of your application can have access to them.</p><p>Another benefit of using Transifex’s SDKs is how easy it is to retrieve languages and currently selected locales. When I used i18next in the previous tutorial, retrieving the current locale had to be done through <a href=\"https://reactjs.org/docs/context.html\">React Context</a>. This concept can seem complex to some, so to be able to easily retrieve the current locale is also a nice plus.</p><p>The Transifex Native React SDK adds an easy interface and components that you can use in your code to remove all the hassles that might come with internationalization. This is a big plus for the developer experience.</p><h1 id=\"conclusion\">Conclusion</h1><p>Transifex is the perfect platform for internationalizing a lot of types of projects, especially React apps. With Transifex Native, you can use the React SDK to add strings to be translated, get languages, get current locale, and more. You can then easily translate the strings from the dashboard and access them whenever.</p><p>I found Transifex Native very easy to use as a developer. Its process allows you to stay efficient and focused on the programming part. When it comes to localization and translating your content, you’ll most likely need the help of other team members, and there’s a chance they won’t know how to do it through editing the source code. <a href=\"https://www.transifex.com/blog/2021/react-i18n-data-backed-benefits-of-transifex-native/\">This is something that you can solve with Transifex</a>. You can also <a href=\"https://docs.transifex.com/localization-tips-workflows/crowdsourcing-translations\">crowdsource</a> your translation if you have an open-source project and need the help of the community.</p><p>Be sure to check out <a href=\"https://docs.transifex.com/javascript-sdk/localize-react-applications\">Transifex’s React SDK documentation</a> to see all the functionalities it provides and see all the cool things you can do with this SDK and platform as a whole.</p>","url":"https://backend.shahednasser.com/how-to-internationalize-i18n-a-react-app-with-transifex-native/","canonical_url":null,"uuid":"0c79a114-bbd3-4c49-bd80-88016561b587","codeinjection_foot":null,"codeinjection_head":null,"codeinjection_styles":null,"comment_id":"61efd82ce37d1cfea32a7e97","reading_time":11,"send_email_when_published":null,"email_subject":null,"childHtmlRehype":{"html":"<p>React is one of the most popular JavaScript frontend frameworks. It allows you to create responsive, reactive, and blazingly fast websites and apps. You can create almost any type of website with React.</p><p>One issue that you’ll run into when you create a React app is internationalizing it. Internationalization (or i18n) is adding support for multiple languages to your website. The process includes both translating the content as well as modifying the style to support the language’s direction.</p><p>There are many solutions out there, and in a previous tutorial, I went through how you can <a href=\"https://blog.shahednasser.com/how-to-internationalize-a-react-app/https://blog.shahednasser.com/how-to-internationalize-a-react-app/\">internationalize a React app using i18next</a>. <a href=\"https://www.i18next.com/\">i18next</a> is an open-source internationalization solution that allows you to internationalize a lot of types of projects, including a React app.</p><p>Another internationalization solution for React is <a href=\"https://www.transifex.com/native/\">Transifex Native</a>. Transifex is a localization platform that makes internationalizing your projects, including your React project, much easier. Transifex bridges the gap between developers and translators, as it allows you to focus on the programming part while also working with translators to translate your website even if they’re not tech-savvy.</p><p>In this article, you’ll learn how to internationalize a React app using Transifex Native. I’ll be creating a website that’s exactly similar to the one I created in my tutorial for internationalization with i18next. This will allow you to see the comparison between the two more clearly and see which is a better option.</p><p>You can find the code for this tutorial on <a href=\"https://github.com/shahednasser/react-transifex-tutorial\">this GitHub repository</a>.</p><h1 id=\"create-a-transifex-account\">Create a Transifex Account</h1><p>The first step that you should take is to <a href=\"https://www.transifex.com/signup/\">create a Transifex account</a>. Transifex has a 15-day free trial and a free-forever plan for open-source projects!</p><p>After you create an account, you’ll be asked to create a project. You’ll need to enter a project name. Then, for project type choose “Native”. Finally, you need to enter the main language of your website and what language(s) you’ll be translating your website to. In my case, I’ll choose English as the main language and Arabic as the target language.</p><figure class=\"kg-card kg-image-card\"><img src=\"https://backend.shahednasser.com/content/images/2022/01/Screen-Shot-2022-01-19-at-11.09.13-AM.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"2000\" height=\"1080\" srcset=\"https://backend.shahednasser.com/content/images/size/w600/2022/01/Screen-Shot-2022-01-19-at-11.09.13-AM.png 600w, https://backend.shahednasser.com/content/images/size/w1000/2022/01/Screen-Shot-2022-01-19-at-11.09.13-AM.png 1000w, https://backend.shahednasser.com/content/images/size/w1600/2022/01/Screen-Shot-2022-01-19-at-11.09.13-AM.png 1600w, https://backend.shahednasser.com/content/images/size/w2400/2022/01/Screen-Shot-2022-01-19-at-11.09.13-AM.png 2400w\" sizes=\"(min-width: 720px) 720px\"></figure><p>Once you’re done, click on <em>Create Project</em>.</p><p>On the next page, you’ll see instructions on how to create credentials for your project. Click on <em>Generate Native Credentials Now</em> at the bottom of the page.</p><figure class=\"kg-card kg-image-card\"><img src=\"https://backend.shahednasser.com/content/images/2022/01/Screen-Shot-2022-01-19-at-11.41.08-AM.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"2000\" height=\"1160\" srcset=\"https://backend.shahednasser.com/content/images/size/w600/2022/01/Screen-Shot-2022-01-19-at-11.41.08-AM.png 600w, https://backend.shahednasser.com/content/images/size/w1000/2022/01/Screen-Shot-2022-01-19-at-11.41.08-AM.png 1000w, https://backend.shahednasser.com/content/images/size/w1600/2022/01/Screen-Shot-2022-01-19-at-11.41.08-AM.png 1600w, https://backend.shahednasser.com/content/images/2022/01/Screen-Shot-2022-01-19-at-11.41.08-AM.png 2018w\" sizes=\"(min-width: 720px) 720px\"></figure><p>This will open a pop-up where you can see the API token and secret. Make sure to copy both the keys as you’ll need them later.</p><p>Once that is done, you can start creating your React app and internationalizing it!</p><h1 id=\"create-react-app\">Create React App</h1><p>In your terminal, run the following command:<br></p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">npx create-react-app transifex-i18n\n</code></pre></div><p>This will create the directory <code class=\"language-text\">transifex-i18n</code> with the React app inside. Change to that directory:<br></p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">cd transifex-i18n\n</code></pre></div><h1 id=\"install-dependencies\">Install Dependencies</h1><p>Now, you’ll install the dependencies that you’ll need for this tutorial. First, install <a href=\"https://react-bootstrap.github.io/\">React Bootstrap</a> for easy styling:<br></p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">npm install react-bootstrap@next bootstrap@5.1.0\n</code></pre></div><p>Then, install Transifex Native’s libraries that are essential for internationalizing a React app:<br></p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">npm install --save @transifex/native @transifex/react @transifex/cli\n</code></pre></div><p><code class=\"language-text\">@transifex/native</code> is the core Transifex Native library. <code class=\"language-text\">@transifex/react</code> is the React SDK that you can use in React projects. It provides an easy and React-compatible interface for the core library. <code class=\"language-text\">@transifex/cli</code> is a CLI tool that you’ll use to sync translatable strings between your codebase and your Transifex Native project.</p><h1 id=\"create-components\">Create Components</h1><p>You’ll now create some components that you’ll use for your website.</p><p>Create <code class=\"language-text\">src/components/Greeting.js</code> with the following content:<br></p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">function Greeting () {\n  return (\n    &#x3C;h1>\n      Hello\n    &#x3C;/h1>\n  );\n}\nexport default Greeting;\n</code></pre></div><p>Create <code class=\"language-text\">src/components/Text.js</code> with the following content:<br></p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">function Text () {\n  return (\n    &#x3C;p>\n      Thank you for visiting our website.\n    &#x3C;/p>\n  )\n}\nexport default Text;\n</code></pre></div><p>Create <code class=\"language-text\">src/components/Navigation.js</code> with the following content:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">import { Container, Nav, Navbar, NavDropdown } from \"react-bootstrap\";\n</code></pre></div><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">import { Container, Nav, Navbar, NavDropdown } from \"react-bootstrap\";\n\nfunction Navigation () {\n\n  return (\n    &#x3C;Navbar bg=\"light\" expand=\"lg\">\n      &#x3C;Container>\n        &#x3C;Navbar.Brand href=\"#\">Transifex React Internationalization&#x3C;/Navbar.Brand>\n        &#x3C;Navbar.Toggle aria-controls=\"basic-navbar-nav\" />\n        &#x3C;Navbar.Collapse id=\"basic-navbar-nav\">\n          &#x3C;Nav className=\"ms-auto\">\n            &#x3C;NavDropdown title=\"Language\" id=\"basic-nav-dropdown\">\n              &#x3C;NavDropdown.Item href=\"#\">English&#x3C;/NavDropdown.Item>\n              &#x3C;NavDropdown.Item href=\"#\">Arabic&#x3C;/NavDropdown.Item>\n            &#x3C;/NavDropdown>\n          &#x3C;/Nav>\n        &#x3C;/Navbar.Collapse>\n      &#x3C;/Container>\n    &#x3C;/Navbar>\n  );\n}\nexport default Navigation;\n</code></pre></div><p>Finally, replace the content of <code class=\"language-text\">src/App.js</code> with the following:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">import React from 'react';\nimport { Container } from 'react-bootstrap';\nimport 'bootstrap/dist/css/bootstrap.min.css';\nimport Greeting from './components/Greeting';\nimport Navigation from './components/Navigation';\nimport Text from './components/Text';\n\nfunction App() {\n\n  return (\n    &#x3C;>\n      &#x3C;Navigation />\n      &#x3C;Container>\n        &#x3C;Greeting />\n        &#x3C;Text />\n      &#x3C;/Container>\n    &#x3C;/>\n  );\n}\nexport default App;\n</code></pre></div><h1 id=\"run-the-website\">Run the Website</h1><p>In your terminal, run the following command to run the website:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">npm start\n</code></pre></div><p>This will open the website in your browser and you can see all the components you just created.</p><figure class=\"kg-card kg-image-card\"><img src=\"https://backend.shahednasser.com/content/images/2022/01/Screen-Shot-2022-01-20-at-10.58.05-AM.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"2000\" height=\"300\" srcset=\"https://backend.shahednasser.com/content/images/size/w600/2022/01/Screen-Shot-2022-01-20-at-10.58.05-AM.png 600w, https://backend.shahednasser.com/content/images/size/w1000/2022/01/Screen-Shot-2022-01-20-at-10.58.05-AM.png 1000w, https://backend.shahednasser.com/content/images/size/w1600/2022/01/Screen-Shot-2022-01-20-at-10.58.05-AM.png 1600w, https://backend.shahednasser.com/content/images/2022/01/Screen-Shot-2022-01-20-at-10.58.05-AM.png 2310w\" sizes=\"(min-width: 720px) 720px\"></figure><h1 id=\"localize-website\">Localize Website</h1><p>At the moment, the website is all in English and you can’t switch between languages or see any translations. You’ll now localize the website using your Transifex account.</p><h2 id=\"initialize-transifex\">Initialize Transifex</h2><p>The first step is to initialize Transifex Native on the website. To do that, add the following import in <code class=\"language-text\">src/App.js</code>:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">import { tx } from '@transifex/native';\n</code></pre></div><p>Then, before the function <code class=\"language-text\">App</code> add the following code to initialize Transifex Native:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">tx.init({\n  token: process.env.REACT_APP_TRANSIFEX_TOKEN,\n});\n</code></pre></div><p>As you can see, you can use the <code class=\"language-text\">init</code> method of <code class=\"language-text\">tx</code> that is imported from the core Transifex Native library. You need to pass it the token that you copied earlier from your Transifex Native credentials. We pass it as a <a href=\"https://create-react-app.dev/docs/adding-custom-environment-variables/\">React environment variable</a>.</p><p>To add the environment variable, create <code class=\"language-text\">.env</code> in the root of your React app with the following:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">REACT_APP_TRANSIFEX_TOKEN=\n</code></pre></div><p>Where the value is the API token that you copied earlier.</p><h2 id=\"add-translatable-strings\">Add Translatable Strings</h2><p>Now, you can make any string translatable. To do that, the Transifex Native React SDK has a component <code class=\"language-text\">T</code> that you can use to indicate that a text is translatable.</p><p>Open <code class=\"language-text\">src/components/Greeting.js</code> and add the import for <code class=\"language-text\">T</code> at the beginning of the file:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">import { T } from '@transifex/react';\n</code></pre></div><p>Then, replace “Hello” with the following:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">&#x3C;T _str=\"Hello\" />\n</code></pre></div><p>As you can see, the component <code class=\"language-text\">T</code> accepts a prop <code class=\"language-text\">_str</code> with the text that can be translated.</p><p><code class=\"language-text\">T</code> can also accept the following props:</p><ol><li><code class=\"language-text\">_context</code>: The context of the string.</li><li><code class=\"language-text\">_key</code>: custom key string</li><li><code class=\"language-text\">_comment</code>: comments from the developer about the string</li><li><code class=\"language-text\">_charlimit</code>: set a character limit for the translator to adhere to</li><li><code class=\"language-text\">_tags</code>: tags separated by commas</li></ol><p>Similarly, open <code class=\"language-text\">src/components/Text.js</code> and add the following import at the beginning of the file:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">import { T } from '@transifex/react';\n</code></pre></div><p>Then, replace <code class=\"language-text\">\"Thank you for visiting our website.\"</code> with the following:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">&#x3C;T _str=\"Thank you for visiting our website.\" />\n</code></pre></div><h2 id=\"push-translation-strings\">Push Translation Strings</h2><p>You just added 2 translatable strings. The next step is to push these strings to your Transifex Native project so they can be viewed on the project dashboard.</p><p>In <code class=\"language-text\">package.json</code> add the following new script:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">\"scripts\": {\n  ...,\n  \"push-translation\": \"txjs-cli push src --token=&#x3C;TOKEN> --secret=&#x3C;SECRET>\"\n}\n</code></pre></div><p>Make sure to replace the <code class=\"language-text\">&#x3C;TOKEN></code> with your API token and <code class=\"language-text\">&#x3C;SECRET></code> with your API secret.</p><p>Using the CLI library that you installed earlier you can push translations to the Transifex Native project using the <code class=\"language-text\">push</code> command. The <code class=\"language-text\">push</code> command takes the directory it should look inside for translatable strings as a parameter. It also needs the token and secret you copied earlier.</p><p>Now, in your terminal, run the following command:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">npm run push-translation\n</code></pre></div><p>After this is run successfully, you’ll see that 2 string resources have been created. If you open the Resources page on your Transifex Native project, you should see that there are 2 strings that need a translation.</p><figure class=\"kg-card kg-image-card\"><img src=\"https://backend.shahednasser.com/content/images/2022/01/Screen-Shot-2022-01-19-at-11.51.16-AM.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"2000\" height=\"423\" srcset=\"https://backend.shahednasser.com/content/images/size/w600/2022/01/Screen-Shot-2022-01-19-at-11.51.16-AM.png 600w, https://backend.shahednasser.com/content/images/size/w1000/2022/01/Screen-Shot-2022-01-19-at-11.51.16-AM.png 1000w, https://backend.shahednasser.com/content/images/size/w1600/2022/01/Screen-Shot-2022-01-19-at-11.51.16-AM.png 1600w, https://backend.shahednasser.com/content/images/2022/01/Screen-Shot-2022-01-19-at-11.51.16-AM.png 2006w\" sizes=\"(min-width: 720px) 720px\"></figure><p>If you click on the Translate button at the top right, you’ll be taken into a new page where you can select the language to translate the strings to. Select the language you want, and then you’ll be able to add the translations for each string using the easy-to-use interface.</p><figure class=\"kg-card kg-image-card\"><img src=\"https://backend.shahednasser.com/content/images/2022/01/Screen-Shot-2022-01-19-at-12.24.25-PM.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"2000\" height=\"765\" srcset=\"https://backend.shahednasser.com/content/images/size/w600/2022/01/Screen-Shot-2022-01-19-at-12.24.25-PM.png 600w, https://backend.shahednasser.com/content/images/size/w1000/2022/01/Screen-Shot-2022-01-19-at-12.24.25-PM.png 1000w, https://backend.shahednasser.com/content/images/size/w1600/2022/01/Screen-Shot-2022-01-19-at-12.24.25-PM.png 1600w, https://backend.shahednasser.com/content/images/size/w2400/2022/01/Screen-Shot-2022-01-19-at-12.24.25-PM.png 2400w\" sizes=\"(min-width: 720px) 720px\"></figure><h2 id=\"change-languages\">Change Languages</h2><p>Ok, so, now you added the translations, but you need to be able to switch between languages on your website to see this change in action.</p><p>The Transifex Native React SDK has the hook <code class=\"language-text\">useLanguages</code> that allows you to retrieve the available languages in your project. You can use that to display the languages and allow the user to switch between them. To change languages, you can use the <code class=\"language-text\">setCurrentLocale</code> method from the core native library.</p><p>Alternatively, you can use the <code class=\"language-text\">[LanguagePicker](https://docs.transifex.com/javascript-sdk/localize-react-applications#languagepicker-component)</code> <a href=\"https://docs.transifex.com/javascript-sdk/localize-react-applications#languagepicker-component\">component</a> from the same SDK that provides the entire UI and functionality ready for you. However, you will not have the ability to customize the UI.</p><p>Open <code class=\"language-text\">src/components/Navigation.js</code> and add the following imports at the beginning of the file:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">import { tx } from '@transifex/native';\nimport { useLanguages } from '@transifex/react';\n</code></pre></div><p>Then, inside the <code class=\"language-text\">Navigation</code> function create a new <code class=\"language-text\">languages</code> variable:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">const languages = useLanguages();\n</code></pre></div><p>Then, replace the elements nested inside <code class=\"language-text\">NavDropdown</code> with the following:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">{languages.map(({code, name}) => (\n  &#x3C;NavDropdown.Item key={code} href=\"#\" onClick={() => tx.setCurrentLocale(code)}>{name}&#x3C;/NavDropdown.Item>\n))}\n</code></pre></div><p>This will loop over the <code class=\"language-text\">languages</code> variable. Each <code class=\"language-text\">language</code> inside it will have <code class=\"language-text\">code</code> and <code class=\"language-text\">name</code> attributes. You use that to display each language as a dropdown item in the navigation bar. When the item is clicked, the language will be changed to the clicked language using <code class=\"language-text\">tx.setCurrentLocale</code>, which accepts the language code (or locale) as a parameter.</p><p>If you open your website now, you should see the languages when you click on the Languages dropdown.</p><figure class=\"kg-card kg-image-card\"><img src=\"https://backend.shahednasser.com/content/images/2022/01/Screen-Shot-2022-01-20-at-11.31.39-AM.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"378\" height=\"316\"></figure><p>Try clicking on the second language, which in my case is Arabic. You’ll see that all the strings will be translated as you translated them in your Transifex Native project dashboard.</p><figure class=\"kg-card kg-image-card\"><img src=\"https://backend.shahednasser.com/content/images/2022/01/Screen-Shot-2022-01-20-at-11.33.37-AM.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"2000\" height=\"230\" srcset=\"https://backend.shahednasser.com/content/images/size/w600/2022/01/Screen-Shot-2022-01-20-at-11.33.37-AM.png 600w, https://backend.shahednasser.com/content/images/size/w1000/2022/01/Screen-Shot-2022-01-20-at-11.33.37-AM.png 1000w, https://backend.shahednasser.com/content/images/size/w1600/2022/01/Screen-Shot-2022-01-20-at-11.33.37-AM.png 1600w, https://backend.shahednasser.com/content/images/size/w2400/2022/01/Screen-Shot-2022-01-20-at-11.33.37-AM.png 2400w\" sizes=\"(min-width: 720px) 720px\"></figure><h2 id=\"translating-more-text\">Translating More Text</h2><p>Let’s now translate the “Language” string in the Navigation component.</p><p>In <code class=\"language-text\">src/components/Navigation.js</code> file add the import for <code class=\"language-text\">T</code>:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">import { T, useLanguages } from '@transifex/react';\n</code></pre></div><p>Then, change the <code class=\"language-text\">title</code> prop of <code class=\"language-text\">NavDropdown</code> to the following:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">title={&#x3C;T _str=\"Language\" />}\n</code></pre></div><p>The <code class=\"language-text\">title</code> prop can accept a component as a value.</p><p>You’ll need to push the new string to the Transifex Native project so run the <code class=\"language-text\">push-translation</code> command again:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">npm run push-translation\n</code></pre></div><p>This will push all new strings and skip already-created strings. If you open your project dashboard now you should see a new string “Language” added there.</p><p>Go ahead and translate the string, then run the website again. You might see that the “Language” string isn’t translated right away when you switch languages. That’s because Transifex Native caches your translations.</p><p>To invalidate the cache, you can use the <code class=\"language-text\">invalidate</code> command of the CLI tool.</p><p>In <code class=\"language-text\">package.json</code> add the new script <code class=\"language-text\">refresh-translation</code> and make changes to the <code class=\"language-text\">start</code> script so that the translations are refreshed whenever the server for your website is started:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">\"scripts\": {\n    \"start\": \"npm run refresh-translation &#x26;&#x26; react-scripts start\",\n    ...,\n    \"refresh-translation\": \"txjs-cli invalidate --token=&#x3C;TOKEN> --secret=&#x3C;SECRET>\"\n  },\n</code></pre></div><p>Just like before, make sure to replace <code class=\"language-text\">&#x3C;TOKEN></code> and <code class=\"language-text\">&#x3C;SECRET></code> with your credentials.</p><p>Now, run the <code class=\"language-text\">start</code> command again or run the <code class=\"language-text\">refresh-translation</code>command on its own. The “Language” string should now be translated when you switch languages.</p><figure class=\"kg-card kg-image-card\"><img src=\"https://backend.shahednasser.com/content/images/2022/01/Screen-Shot-2022-01-19-at-1.04.05-PM-1.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"2000\" height=\"252\" srcset=\"https://backend.shahednasser.com/content/images/size/w600/2022/01/Screen-Shot-2022-01-19-at-1.04.05-PM-1.png 600w, https://backend.shahednasser.com/content/images/size/w1000/2022/01/Screen-Shot-2022-01-19-at-1.04.05-PM-1.png 1000w, https://backend.shahednasser.com/content/images/size/w1600/2022/01/Screen-Shot-2022-01-19-at-1.04.05-PM-1.png 1600w, https://backend.shahednasser.com/content/images/size/w2400/2022/01/Screen-Shot-2022-01-19-at-1.04.05-PM-1.png 2400w\" sizes=\"(min-width: 720px) 720px\"></figure><h1 id=\"changing-layout\">Changing Layout</h1><p>The next part of internationalization is making sure that the layout conforms with the selected language’s directionality. As Arabic is a right-to-left (RTL) language, the layout needs to be flipped when the Arabic language is chosen.</p><p>The Transifex Native React SDK has a <code class=\"language-text\">useLocale</code> hook that you can use to retrieve the current chosen locale. We’ll use that to change the document direction and make any necessary changes based on the current language.</p><p>In <code class=\"language-text\">src/App.js</code> add imports at the beginning of the file:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">import React, { useEffect } from 'react';\nimport { useLocale } from '@transifex/react';\n</code></pre></div><p>Then, inside the <code class=\"language-text\">App</code> function, add the following before the <code class=\"language-text\">return</code>statement:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">const locale = useLocale();\nuseEffect(() => {\n  if (locale) {\n    document.body.style.direction = locale === 'en' ? 'ltr' : 'rtl';\n  }\n}, [locale]);\n</code></pre></div><p>You first retrieve the locale using <code class=\"language-text\">useLocale</code>. Then, whenever <code class=\"language-text\">locale</code> is changed, you change the <code class=\"language-text\">direction</code> style property of the <code class=\"language-text\">body</code> of the page based on the locale.</p><p>Next, in <code class=\"language-text\">src/components/Navbar.js</code> add the necessary import for <code class=\"language-text\">useLocale</code>:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">import { T, useLanguages, useLocale } from '@transifex/react';\n</code></pre></div><p>Then, create the <code class=\"language-text\">locale</code> variable inside the <code class=\"language-text\">Navigation</code> function:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">const locale = useLocale();\n</code></pre></div><p>Finally, change the <code class=\"language-text\">className</code> prop of the <code class=\"language-text\">Nav</code> element to the following:</p><div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">className={!locale || locale === 'en' ? \"ms-auto\" : \"me-auto\"}\n</code></pre></div><p>This will make sure that when the language is English the “Language” dropdown will appear at the right, otherwise, it will appear on the left.</p><p>Now, open the website and switch to an RTL language. You should see that the layout has changed.</p><figure class=\"kg-card kg-image-card\"><img src=\"https://backend.shahednasser.com/content/images/2022/01/Screen-Shot-2022-01-19-at-1.06.24-PM.png\" class=\"kg-image\" alt=\"\" loading=\"lazy\" width=\"2000\" height=\"329\" srcset=\"https://backend.shahednasser.com/content/images/size/w600/2022/01/Screen-Shot-2022-01-19-at-1.06.24-PM.png 600w, https://backend.shahednasser.com/content/images/size/w1000/2022/01/Screen-Shot-2022-01-19-at-1.06.24-PM.png 1000w, https://backend.shahednasser.com/content/images/size/w1600/2022/01/Screen-Shot-2022-01-19-at-1.06.24-PM.png 1600w, https://backend.shahednasser.com/content/images/size/w2400/2022/01/Screen-Shot-2022-01-19-at-1.06.24-PM.png 2400w\" sizes=\"(min-width: 720px) 720px\"></figure><p>If you try to switch back to English, the layout will go back to the way it was.</p><h1 id=\"benefits-of-transifex-native-react-sdk\">Benefits of Transifex Native React SDK</h1><p>If you went through the previous i18next tutorial, or you already know how i18next works, and you went through this tutorial, you can easily spot all the benefits of the Transifex Native React SDK.</p><p>The main benefit of using Transifex Native is that the translations are not part of your codebase. For bigger projects or projects that require translators that aren’t tech-savvy, this makes it much easier to translate a website, as the translation can all happen from the dashboard. Developers can then just focus on developing the website as necessary.</p><p>This is also very beneficial for projects that include multiple environments. If you have a website, an iOS app, and an Android app, it’s a hassle to internationalize all these different projects as they each have a different way of translating string resources. As Transifex has <a href=\"https://docs.transifex.com/getting-started-with-native/getting-started-with-transifex-native\">SDKs for all these types of projects</a>, and as it also has <a href=\"https://transifex.github.io/openapi/index.html\">REST APIs</a> that allow you to access your project resources from basically anywhere, all you need is to translate these strings on the Transifex Native project dashboard and any component of your application can have access to them.</p><p>Another benefit of using Transifex’s SDKs is how easy it is to retrieve languages and currently selected locales. When I used i18next in the previous tutorial, retrieving the current locale had to be done through <a href=\"https://reactjs.org/docs/context.html\">React Context</a>. This concept can seem complex to some, so to be able to easily retrieve the current locale is also a nice plus.</p><p>The Transifex Native React SDK adds an easy interface and components that you can use in your code to remove all the hassles that might come with internationalization. This is a big plus for the developer experience.</p><h1 id=\"conclusion\">Conclusion</h1><p>Transifex is the perfect platform for internationalizing a lot of types of projects, especially React apps. With Transifex Native, you can use the React SDK to add strings to be translated, get languages, get current locale, and more. You can then easily translate the strings from the dashboard and access them whenever.</p><p>I found Transifex Native very easy to use as a developer. Its process allows you to stay efficient and focused on the programming part. When it comes to localization and translating your content, you’ll most likely need the help of other team members, and there’s a chance they won’t know how to do it through editing the source code. <a href=\"https://www.transifex.com/blog/2021/react-i18n-data-backed-benefits-of-transifex-native/\">This is something that you can solve with Transifex</a>. You can also <a href=\"https://docs.transifex.com/localization-tips-workflows/crowdsourcing-translations\">crowdsource</a> your translation if you have an open-source project and need the help of the community.</p><p>Be sure to check out <a href=\"https://docs.transifex.com/javascript-sdk/localize-react-applications\">Transifex’s React SDK documentation</a> to see all the functionalities it provides and see all the cool things you can do with this SDK and platform as a whole.</p>","htmlAst":{"type":"root","children":[{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"React is one of the most popular JavaScript frontend frameworks. It allows you to create responsive, reactive, and blazingly fast websites and apps. You can create almost any type of website with React."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"One issue that you’ll run into when you create a React app is internationalizing it. Internationalization (or i18n) is adding support for multiple languages to your website. The process includes both translating the content as well as modifying the style to support the language’s direction."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"There are many solutions out there, and in a previous tutorial, I went through how you can "},{"type":"element","tagName":"a","properties":{"href":"https://blog.shahednasser.com/how-to-internationalize-a-react-app/https://blog.shahednasser.com/how-to-internationalize-a-react-app/"},"children":[{"type":"text","value":"internationalize a React app using i18next"}]},{"type":"text","value":". "},{"type":"element","tagName":"a","properties":{"href":"https://www.i18next.com/"},"children":[{"type":"text","value":"i18next"}]},{"type":"text","value":" is an open-source internationalization solution that allows you to internationalize a lot of types of projects, including a React app."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Another internationalization solution for React is "},{"type":"element","tagName":"a","properties":{"href":"https://www.transifex.com/native/"},"children":[{"type":"text","value":"Transifex Native"}]},{"type":"text","value":". Transifex is a localization platform that makes internationalizing your projects, including your React project, much easier. Transifex bridges the gap between developers and translators, as it allows you to focus on the programming part while also working with translators to translate your website even if they’re not tech-savvy."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"In this article, you’ll learn how to internationalize a React app using Transifex Native. I’ll be creating a website that’s exactly similar to the one I created in my tutorial for internationalization with i18next. This will allow you to see the comparison between the two more clearly and see which is a better option."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"You can find the code for this tutorial on "},{"type":"element","tagName":"a","properties":{"href":"https://github.com/shahednasser/react-transifex-tutorial"},"children":[{"type":"text","value":"this GitHub repository"}]},{"type":"text","value":"."}]},{"type":"element","tagName":"h1","properties":{"id":"create-a-transifex-account"},"children":[{"type":"text","value":"Create a Transifex Account"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"The first step that you should take is to "},{"type":"element","tagName":"a","properties":{"href":"https://www.transifex.com/signup/"},"children":[{"type":"text","value":"create a Transifex account"}]},{"type":"text","value":". Transifex has a 15-day free trial and a free-forever plan for open-source projects!"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"After you create an account, you’ll be asked to create a project. You’ll need to enter a project name. Then, for project type choose “Native”. Finally, you need to enter the main language of your website and what language(s) you’ll be translating your website to. In my case, I’ll choose English as the main language and Arabic as the target language."}]},{"type":"element","tagName":"figure","properties":{"className":["kg-card","kg-image-card"]},"children":[{"type":"element","tagName":"img","properties":{"src":"https://backend.shahednasser.com/content/images/2022/01/Screen-Shot-2022-01-19-at-11.09.13-AM.png","className":["kg-image"],"alt":"","loading":"lazy","width":2000,"height":1080,"srcSet":["https://backend.shahednasser.com/content/images/size/w600/2022/01/Screen-Shot-2022-01-19-at-11.09.13-AM.png 600w","https://backend.shahednasser.com/content/images/size/w1000/2022/01/Screen-Shot-2022-01-19-at-11.09.13-AM.png 1000w","https://backend.shahednasser.com/content/images/size/w1600/2022/01/Screen-Shot-2022-01-19-at-11.09.13-AM.png 1600w","https://backend.shahednasser.com/content/images/size/w2400/2022/01/Screen-Shot-2022-01-19-at-11.09.13-AM.png 2400w"],"sizes":"(min-width: 720px) 720px"},"children":[]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Once you’re done, click on "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"Create Project"}]},{"type":"text","value":"."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"On the next page, you’ll see instructions on how to create credentials for your project. Click on "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"Generate Native Credentials Now"}]},{"type":"text","value":" at the bottom of the page."}]},{"type":"element","tagName":"figure","properties":{"className":["kg-card","kg-image-card"]},"children":[{"type":"element","tagName":"img","properties":{"src":"https://backend.shahednasser.com/content/images/2022/01/Screen-Shot-2022-01-19-at-11.41.08-AM.png","className":["kg-image"],"alt":"","loading":"lazy","width":2000,"height":1160,"srcSet":["https://backend.shahednasser.com/content/images/size/w600/2022/01/Screen-Shot-2022-01-19-at-11.41.08-AM.png 600w","https://backend.shahednasser.com/content/images/size/w1000/2022/01/Screen-Shot-2022-01-19-at-11.41.08-AM.png 1000w","https://backend.shahednasser.com/content/images/size/w1600/2022/01/Screen-Shot-2022-01-19-at-11.41.08-AM.png 1600w","https://backend.shahednasser.com/content/images/2022/01/Screen-Shot-2022-01-19-at-11.41.08-AM.png 2018w"],"sizes":"(min-width: 720px) 720px"},"children":[]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"This will open a pop-up where you can see the API token and secret. Make sure to copy both the keys as you’ll need them later."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Once that is done, you can start creating your React app and internationalizing it!"}]},{"type":"element","tagName":"h1","properties":{"id":"create-react-app"},"children":[{"type":"text","value":"Create React App"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"In your terminal, run the following command:"},{"type":"element","tagName":"br","properties":{},"children":[]}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"npx create-react-app transifex-i18n\n"}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"This will create the directory "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"transifex-i18n"}]},{"type":"text","value":" with the React app inside. Change to that directory:"},{"type":"element","tagName":"br","properties":{},"children":[]}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"cd transifex-i18n\n"}]}]}]},{"type":"element","tagName":"h1","properties":{"id":"install-dependencies"},"children":[{"type":"text","value":"Install Dependencies"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Now, you’ll install the dependencies that you’ll need for this tutorial. First, install "},{"type":"element","tagName":"a","properties":{"href":"https://react-bootstrap.github.io/"},"children":[{"type":"text","value":"React Bootstrap"}]},{"type":"text","value":" for easy styling:"},{"type":"element","tagName":"br","properties":{},"children":[]}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"npm install react-bootstrap@next bootstrap@5.1.0\n"}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Then, install Transifex Native’s libraries that are essential for internationalizing a React app:"},{"type":"element","tagName":"br","properties":{},"children":[]}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"npm install --save @transifex/native @transifex/react @transifex/cli\n"}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"@transifex/native"}]},{"type":"text","value":" is the core Transifex Native library. "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"@transifex/react"}]},{"type":"text","value":" is the React SDK that you can use in React projects. It provides an easy and React-compatible interface for the core library. "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"@transifex/cli"}]},{"type":"text","value":" is a CLI tool that you’ll use to sync translatable strings between your codebase and your Transifex Native project."}]},{"type":"element","tagName":"h1","properties":{"id":"create-components"},"children":[{"type":"text","value":"Create Components"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"You’ll now create some components that you’ll use for your website."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Create "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"src/components/Greeting.js"}]},{"type":"text","value":" with the following content:"},{"type":"element","tagName":"br","properties":{},"children":[]}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"function Greeting () {\n  return (\n    <h1>\n      Hello\n    </h1>\n  );\n}\nexport default Greeting;\n"}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Create "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"src/components/Text.js"}]},{"type":"text","value":" with the following content:"},{"type":"element","tagName":"br","properties":{},"children":[]}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"function Text () {\n  return (\n    <p>\n      Thank you for visiting our website.\n    </p>\n  )\n}\nexport default Text;\n"}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Create "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"src/components/Navigation.js"}]},{"type":"text","value":" with the following content:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"import { Container, Nav, Navbar, NavDropdown } from \"react-bootstrap\";\n"}]}]}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"import { Container, Nav, Navbar, NavDropdown } from \"react-bootstrap\";\n\nfunction Navigation () {\n\n  return (\n    <Navbar bg=\"light\" expand=\"lg\">\n      <Container>\n        <Navbar.Brand href=\"#\">Transifex React Internationalization</Navbar.Brand>\n        <Navbar.Toggle aria-controls=\"basic-navbar-nav\" />\n        <Navbar.Collapse id=\"basic-navbar-nav\">\n          <Nav className=\"ms-auto\">\n            <NavDropdown title=\"Language\" id=\"basic-nav-dropdown\">\n              <NavDropdown.Item href=\"#\">English</NavDropdown.Item>\n              <NavDropdown.Item href=\"#\">Arabic</NavDropdown.Item>\n            </NavDropdown>\n          </Nav>\n        </Navbar.Collapse>\n      </Container>\n    </Navbar>\n  );\n}\nexport default Navigation;\n"}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Finally, replace the content of "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"src/App.js"}]},{"type":"text","value":" with the following:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"import React from 'react';\nimport { Container } from 'react-bootstrap';\nimport 'bootstrap/dist/css/bootstrap.min.css';\nimport Greeting from './components/Greeting';\nimport Navigation from './components/Navigation';\nimport Text from './components/Text';\n\nfunction App() {\n\n  return (\n    <>\n      <Navigation />\n      <Container>\n        <Greeting />\n        <Text />\n      </Container>\n    </>\n  );\n}\nexport default App;\n"}]}]}]},{"type":"element","tagName":"h1","properties":{"id":"run-the-website"},"children":[{"type":"text","value":"Run the Website"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"In your terminal, run the following command to run the website:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"npm start\n"}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"This will open the website in your browser and you can see all the components you just created."}]},{"type":"element","tagName":"figure","properties":{"className":["kg-card","kg-image-card"]},"children":[{"type":"element","tagName":"img","properties":{"src":"https://backend.shahednasser.com/content/images/2022/01/Screen-Shot-2022-01-20-at-10.58.05-AM.png","className":["kg-image"],"alt":"","loading":"lazy","width":2000,"height":300,"srcSet":["https://backend.shahednasser.com/content/images/size/w600/2022/01/Screen-Shot-2022-01-20-at-10.58.05-AM.png 600w","https://backend.shahednasser.com/content/images/size/w1000/2022/01/Screen-Shot-2022-01-20-at-10.58.05-AM.png 1000w","https://backend.shahednasser.com/content/images/size/w1600/2022/01/Screen-Shot-2022-01-20-at-10.58.05-AM.png 1600w","https://backend.shahednasser.com/content/images/2022/01/Screen-Shot-2022-01-20-at-10.58.05-AM.png 2310w"],"sizes":"(min-width: 720px) 720px"},"children":[]}]},{"type":"element","tagName":"h1","properties":{"id":"localize-website"},"children":[{"type":"text","value":"Localize Website"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"At the moment, the website is all in English and you can’t switch between languages or see any translations. You’ll now localize the website using your Transifex account."}]},{"type":"element","tagName":"h2","properties":{"id":"initialize-transifex"},"children":[{"type":"text","value":"Initialize Transifex"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"The first step is to initialize Transifex Native on the website. To do that, add the following import in "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"src/App.js"}]},{"type":"text","value":":"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"import { tx } from '@transifex/native';\n"}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Then, before the function "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"App"}]},{"type":"text","value":" add the following code to initialize Transifex Native:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"tx.init({\n  token: process.env.REACT_APP_TRANSIFEX_TOKEN,\n});\n"}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"As you can see, you can use the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"init"}]},{"type":"text","value":" method of "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"tx"}]},{"type":"text","value":" that is imported from the core Transifex Native library. You need to pass it the token that you copied earlier from your Transifex Native credentials. We pass it as a "},{"type":"element","tagName":"a","properties":{"href":"https://create-react-app.dev/docs/adding-custom-environment-variables/"},"children":[{"type":"text","value":"React environment variable"}]},{"type":"text","value":"."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"To add the environment variable, create "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":".env"}]},{"type":"text","value":" in the root of your React app with the following:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"REACT_APP_TRANSIFEX_TOKEN=\n"}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Where the value is the API token that you copied earlier."}]},{"type":"element","tagName":"h2","properties":{"id":"add-translatable-strings"},"children":[{"type":"text","value":"Add Translatable Strings"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Now, you can make any string translatable. To do that, the Transifex Native React SDK has a component "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"T"}]},{"type":"text","value":" that you can use to indicate that a text is translatable."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Open "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"src/components/Greeting.js"}]},{"type":"text","value":" and add the import for "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"T"}]},{"type":"text","value":" at the beginning of the file:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"import { T } from '@transifex/react';\n"}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Then, replace “Hello” with the following:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"<T _str=\"Hello\" />\n"}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"As you can see, the component "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"T"}]},{"type":"text","value":" accepts a prop "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"_str"}]},{"type":"text","value":" with the text that can be translated."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"T"}]},{"type":"text","value":" can also accept the following props:"}]},{"type":"element","tagName":"ol","properties":{},"children":[{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"_context"}]},{"type":"text","value":": The context of the string."}]},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"_key"}]},{"type":"text","value":": custom key string"}]},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"_comment"}]},{"type":"text","value":": comments from the developer about the string"}]},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"_charlimit"}]},{"type":"text","value":": set a character limit for the translator to adhere to"}]},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"_tags"}]},{"type":"text","value":": tags separated by commas"}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Similarly, open "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"src/components/Text.js"}]},{"type":"text","value":" and add the following import at the beginning of the file:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"import { T } from '@transifex/react';\n"}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Then, replace "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"\"Thank you for visiting our website.\""}]},{"type":"text","value":" with the following:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"<T _str=\"Thank you for visiting our website.\" />\n"}]}]}]},{"type":"element","tagName":"h2","properties":{"id":"push-translation-strings"},"children":[{"type":"text","value":"Push Translation Strings"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"You just added 2 translatable strings. The next step is to push these strings to your Transifex Native project so they can be viewed on the project dashboard."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"In "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"package.json"}]},{"type":"text","value":" add the following new script:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"\"scripts\": {\n  ...,\n  \"push-translation\": \"txjs-cli push src --token=<TOKEN> --secret=<SECRET>\"\n}\n"}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Make sure to replace the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"<TOKEN>"}]},{"type":"text","value":" with your API token and "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"<SECRET>"}]},{"type":"text","value":" with your API secret."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Using the CLI library that you installed earlier you can push translations to the Transifex Native project using the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"push"}]},{"type":"text","value":" command. The "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"push"}]},{"type":"text","value":" command takes the directory it should look inside for translatable strings as a parameter. It also needs the token and secret you copied earlier."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Now, in your terminal, run the following command:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"npm run push-translation\n"}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"After this is run successfully, you’ll see that 2 string resources have been created. If you open the Resources page on your Transifex Native project, you should see that there are 2 strings that need a translation."}]},{"type":"element","tagName":"figure","properties":{"className":["kg-card","kg-image-card"]},"children":[{"type":"element","tagName":"img","properties":{"src":"https://backend.shahednasser.com/content/images/2022/01/Screen-Shot-2022-01-19-at-11.51.16-AM.png","className":["kg-image"],"alt":"","loading":"lazy","width":2000,"height":423,"srcSet":["https://backend.shahednasser.com/content/images/size/w600/2022/01/Screen-Shot-2022-01-19-at-11.51.16-AM.png 600w","https://backend.shahednasser.com/content/images/size/w1000/2022/01/Screen-Shot-2022-01-19-at-11.51.16-AM.png 1000w","https://backend.shahednasser.com/content/images/size/w1600/2022/01/Screen-Shot-2022-01-19-at-11.51.16-AM.png 1600w","https://backend.shahednasser.com/content/images/2022/01/Screen-Shot-2022-01-19-at-11.51.16-AM.png 2006w"],"sizes":"(min-width: 720px) 720px"},"children":[]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"If you click on the Translate button at the top right, you’ll be taken into a new page where you can select the language to translate the strings to. Select the language you want, and then you’ll be able to add the translations for each string using the easy-to-use interface."}]},{"type":"element","tagName":"figure","properties":{"className":["kg-card","kg-image-card"]},"children":[{"type":"element","tagName":"img","properties":{"src":"https://backend.shahednasser.com/content/images/2022/01/Screen-Shot-2022-01-19-at-12.24.25-PM.png","className":["kg-image"],"alt":"","loading":"lazy","width":2000,"height":765,"srcSet":["https://backend.shahednasser.com/content/images/size/w600/2022/01/Screen-Shot-2022-01-19-at-12.24.25-PM.png 600w","https://backend.shahednasser.com/content/images/size/w1000/2022/01/Screen-Shot-2022-01-19-at-12.24.25-PM.png 1000w","https://backend.shahednasser.com/content/images/size/w1600/2022/01/Screen-Shot-2022-01-19-at-12.24.25-PM.png 1600w","https://backend.shahednasser.com/content/images/size/w2400/2022/01/Screen-Shot-2022-01-19-at-12.24.25-PM.png 2400w"],"sizes":"(min-width: 720px) 720px"},"children":[]}]},{"type":"element","tagName":"h2","properties":{"id":"change-languages"},"children":[{"type":"text","value":"Change Languages"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Ok, so, now you added the translations, but you need to be able to switch between languages on your website to see this change in action."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"The Transifex Native React SDK has the hook "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"useLanguages"}]},{"type":"text","value":" that allows you to retrieve the available languages in your project. You can use that to display the languages and allow the user to switch between them. To change languages, you can use the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"setCurrentLocale"}]},{"type":"text","value":" method from the core native library."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Alternatively, you can use the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"[LanguagePicker](https://docs.transifex.com/javascript-sdk/localize-react-applications#languagepicker-component)"}]},{"type":"text","value":" "},{"type":"element","tagName":"a","properties":{"href":"https://docs.transifex.com/javascript-sdk/localize-react-applications#languagepicker-component"},"children":[{"type":"text","value":"component"}]},{"type":"text","value":" from the same SDK that provides the entire UI and functionality ready for you. However, you will not have the ability to customize the UI."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Open "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"src/components/Navigation.js"}]},{"type":"text","value":" and add the following imports at the beginning of the file:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"import { tx } from '@transifex/native';\nimport { useLanguages } from '@transifex/react';\n"}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Then, inside the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"Navigation"}]},{"type":"text","value":" function create a new "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"languages"}]},{"type":"text","value":" variable:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"const languages = useLanguages();\n"}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Then, replace the elements nested inside "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"NavDropdown"}]},{"type":"text","value":" with the following:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"{languages.map(({code, name}) => (\n  <NavDropdown.Item key={code} href=\"#\" onClick={() => tx.setCurrentLocale(code)}>{name}</NavDropdown.Item>\n))}\n"}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"This will loop over the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"languages"}]},{"type":"text","value":" variable. Each "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"language"}]},{"type":"text","value":" inside it will have "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"code"}]},{"type":"text","value":" and "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"name"}]},{"type":"text","value":" attributes. You use that to display each language as a dropdown item in the navigation bar. When the item is clicked, the language will be changed to the clicked language using "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"tx.setCurrentLocale"}]},{"type":"text","value":", which accepts the language code (or locale) as a parameter."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"If you open your website now, you should see the languages when you click on the Languages dropdown."}]},{"type":"element","tagName":"figure","properties":{"className":["kg-card","kg-image-card"]},"children":[{"type":"element","tagName":"img","properties":{"src":"https://backend.shahednasser.com/content/images/2022/01/Screen-Shot-2022-01-20-at-11.31.39-AM.png","className":["kg-image"],"alt":"","loading":"lazy","width":378,"height":316},"children":[]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Try clicking on the second language, which in my case is Arabic. You’ll see that all the strings will be translated as you translated them in your Transifex Native project dashboard."}]},{"type":"element","tagName":"figure","properties":{"className":["kg-card","kg-image-card"]},"children":[{"type":"element","tagName":"img","properties":{"src":"https://backend.shahednasser.com/content/images/2022/01/Screen-Shot-2022-01-20-at-11.33.37-AM.png","className":["kg-image"],"alt":"","loading":"lazy","width":2000,"height":230,"srcSet":["https://backend.shahednasser.com/content/images/size/w600/2022/01/Screen-Shot-2022-01-20-at-11.33.37-AM.png 600w","https://backend.shahednasser.com/content/images/size/w1000/2022/01/Screen-Shot-2022-01-20-at-11.33.37-AM.png 1000w","https://backend.shahednasser.com/content/images/size/w1600/2022/01/Screen-Shot-2022-01-20-at-11.33.37-AM.png 1600w","https://backend.shahednasser.com/content/images/size/w2400/2022/01/Screen-Shot-2022-01-20-at-11.33.37-AM.png 2400w"],"sizes":"(min-width: 720px) 720px"},"children":[]}]},{"type":"element","tagName":"h2","properties":{"id":"translating-more-text"},"children":[{"type":"text","value":"Translating More Text"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Let’s now translate the “Language” string in the Navigation component."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"In "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"src/components/Navigation.js"}]},{"type":"text","value":" file add the import for "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"T"}]},{"type":"text","value":":"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"import { T, useLanguages } from '@transifex/react';\n"}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Then, change the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"title"}]},{"type":"text","value":" prop of "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"NavDropdown"}]},{"type":"text","value":" to the following:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"title={<T _str=\"Language\" />}\n"}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"The "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"title"}]},{"type":"text","value":" prop can accept a component as a value."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"You’ll need to push the new string to the Transifex Native project so run the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"push-translation"}]},{"type":"text","value":" command again:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"npm run push-translation\n"}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"This will push all new strings and skip already-created strings. If you open your project dashboard now you should see a new string “Language” added there."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Go ahead and translate the string, then run the website again. You might see that the “Language” string isn’t translated right away when you switch languages. That’s because Transifex Native caches your translations."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"To invalidate the cache, you can use the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"invalidate"}]},{"type":"text","value":" command of the CLI tool."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"In "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"package.json"}]},{"type":"text","value":" add the new script "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"refresh-translation"}]},{"type":"text","value":" and make changes to the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"start"}]},{"type":"text","value":" script so that the translations are refreshed whenever the server for your website is started:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"\"scripts\": {\n    \"start\": \"npm run refresh-translation && react-scripts start\",\n    ...,\n    \"refresh-translation\": \"txjs-cli invalidate --token=<TOKEN> --secret=<SECRET>\"\n  },\n"}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Just like before, make sure to replace "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"<TOKEN>"}]},{"type":"text","value":" and "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"<SECRET>"}]},{"type":"text","value":" with your credentials."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Now, run the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"start"}]},{"type":"text","value":" command again or run the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"refresh-translation"}]},{"type":"text","value":"command on its own. The “Language” string should now be translated when you switch languages."}]},{"type":"element","tagName":"figure","properties":{"className":["kg-card","kg-image-card"]},"children":[{"type":"element","tagName":"img","properties":{"src":"https://backend.shahednasser.com/content/images/2022/01/Screen-Shot-2022-01-19-at-1.04.05-PM-1.png","className":["kg-image"],"alt":"","loading":"lazy","width":2000,"height":252,"srcSet":["https://backend.shahednasser.com/content/images/size/w600/2022/01/Screen-Shot-2022-01-19-at-1.04.05-PM-1.png 600w","https://backend.shahednasser.com/content/images/size/w1000/2022/01/Screen-Shot-2022-01-19-at-1.04.05-PM-1.png 1000w","https://backend.shahednasser.com/content/images/size/w1600/2022/01/Screen-Shot-2022-01-19-at-1.04.05-PM-1.png 1600w","https://backend.shahednasser.com/content/images/size/w2400/2022/01/Screen-Shot-2022-01-19-at-1.04.05-PM-1.png 2400w"],"sizes":"(min-width: 720px) 720px"},"children":[]}]},{"type":"element","tagName":"h1","properties":{"id":"changing-layout"},"children":[{"type":"text","value":"Changing Layout"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"The next part of internationalization is making sure that the layout conforms with the selected language’s directionality. As Arabic is a right-to-left (RTL) language, the layout needs to be flipped when the Arabic language is chosen."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"The Transifex Native React SDK has a "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"useLocale"}]},{"type":"text","value":" hook that you can use to retrieve the current chosen locale. We’ll use that to change the document direction and make any necessary changes based on the current language."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"In "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"src/App.js"}]},{"type":"text","value":" add imports at the beginning of the file:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"import React, { useEffect } from 'react';\nimport { useLocale } from '@transifex/react';\n"}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Then, inside the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"App"}]},{"type":"text","value":" function, add the following before the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":"statement:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"const locale = useLocale();\nuseEffect(() => {\n  if (locale) {\n    document.body.style.direction = locale === 'en' ? 'ltr' : 'rtl';\n  }\n}, [locale]);\n"}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"You first retrieve the locale using "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"useLocale"}]},{"type":"text","value":". Then, whenever "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"locale"}]},{"type":"text","value":" is changed, you change the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"direction"}]},{"type":"text","value":" style property of the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"body"}]},{"type":"text","value":" of the page based on the locale."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Next, in "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"src/components/Navbar.js"}]},{"type":"text","value":" add the necessary import for "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"useLocale"}]},{"type":"text","value":":"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"import { T, useLanguages, useLocale } from '@transifex/react';\n"}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Then, create the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"locale"}]},{"type":"text","value":" variable inside the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"Navigation"}]},{"type":"text","value":" function:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"const locale = useLocale();\n"}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Finally, change the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"className"}]},{"type":"text","value":" prop of the "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"Nav"}]},{"type":"text","value":" element to the following:"}]},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"className={!locale || locale === 'en' ? \"ms-auto\" : \"me-auto\"}\n"}]}]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"This will make sure that when the language is English the “Language” dropdown will appear at the right, otherwise, it will appear on the left."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Now, open the website and switch to an RTL language. You should see that the layout has changed."}]},{"type":"element","tagName":"figure","properties":{"className":["kg-card","kg-image-card"]},"children":[{"type":"element","tagName":"img","properties":{"src":"https://backend.shahednasser.com/content/images/2022/01/Screen-Shot-2022-01-19-at-1.06.24-PM.png","className":["kg-image"],"alt":"","loading":"lazy","width":2000,"height":329,"srcSet":["https://backend.shahednasser.com/content/images/size/w600/2022/01/Screen-Shot-2022-01-19-at-1.06.24-PM.png 600w","https://backend.shahednasser.com/content/images/size/w1000/2022/01/Screen-Shot-2022-01-19-at-1.06.24-PM.png 1000w","https://backend.shahednasser.com/content/images/size/w1600/2022/01/Screen-Shot-2022-01-19-at-1.06.24-PM.png 1600w","https://backend.shahednasser.com/content/images/size/w2400/2022/01/Screen-Shot-2022-01-19-at-1.06.24-PM.png 2400w"],"sizes":"(min-width: 720px) 720px"},"children":[]}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"If you try to switch back to English, the layout will go back to the way it was."}]},{"type":"element","tagName":"h1","properties":{"id":"benefits-of-transifex-native-react-sdk"},"children":[{"type":"text","value":"Benefits of Transifex Native React SDK"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"If you went through the previous i18next tutorial, or you already know how i18next works, and you went through this tutorial, you can easily spot all the benefits of the Transifex Native React SDK."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"The main benefit of using Transifex Native is that the translations are not part of your codebase. For bigger projects or projects that require translators that aren’t tech-savvy, this makes it much easier to translate a website, as the translation can all happen from the dashboard. Developers can then just focus on developing the website as necessary."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"This is also very beneficial for projects that include multiple environments. If you have a website, an iOS app, and an Android app, it’s a hassle to internationalize all these different projects as they each have a different way of translating string resources. As Transifex has "},{"type":"element","tagName":"a","properties":{"href":"https://docs.transifex.com/getting-started-with-native/getting-started-with-transifex-native"},"children":[{"type":"text","value":"SDKs for all these types of projects"}]},{"type":"text","value":", and as it also has "},{"type":"element","tagName":"a","properties":{"href":"https://transifex.github.io/openapi/index.html"},"children":[{"type":"text","value":"REST APIs"}]},{"type":"text","value":" that allow you to access your project resources from basically anywhere, all you need is to translate these strings on the Transifex Native project dashboard and any component of your application can have access to them."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Another benefit of using Transifex’s SDKs is how easy it is to retrieve languages and currently selected locales. When I used i18next in the previous tutorial, retrieving the current locale had to be done through "},{"type":"element","tagName":"a","properties":{"href":"https://reactjs.org/docs/context.html"},"children":[{"type":"text","value":"React Context"}]},{"type":"text","value":". This concept can seem complex to some, so to be able to easily retrieve the current locale is also a nice plus."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"The Transifex Native React SDK adds an easy interface and components that you can use in your code to remove all the hassles that might come with internationalization. This is a big plus for the developer experience."}]},{"type":"element","tagName":"h1","properties":{"id":"conclusion"},"children":[{"type":"text","value":"Conclusion"}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Transifex is the perfect platform for internationalizing a lot of types of projects, especially React apps. With Transifex Native, you can use the React SDK to add strings to be translated, get languages, get current locale, and more. You can then easily translate the strings from the dashboard and access them whenever."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"I found Transifex Native very easy to use as a developer. Its process allows you to stay efficient and focused on the programming part. When it comes to localization and translating your content, you’ll most likely need the help of other team members, and there’s a chance they won’t know how to do it through editing the source code. "},{"type":"element","tagName":"a","properties":{"href":"https://www.transifex.com/blog/2021/react-i18n-data-backed-benefits-of-transifex-native/"},"children":[{"type":"text","value":"This is something that you can solve with Transifex"}]},{"type":"text","value":". You can also "},{"type":"element","tagName":"a","properties":{"href":"https://docs.transifex.com/localization-tips-workflows/crowdsourcing-translations"},"children":[{"type":"text","value":"crowdsource"}]},{"type":"text","value":" your translation if you have an open-source project and need the help of the community."}]},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Be sure to check out "},{"type":"element","tagName":"a","properties":{"href":"https://docs.transifex.com/javascript-sdk/localize-react-applications"},"children":[{"type":"text","value":"Transifex’s React SDK documentation"}]},{"type":"text","value":" to see all the functionalities it provides and see all the cool things you can do with this SDK and platform as a whole."}]}],"data":{"quirksMode":false}},"tableOfContents":[{"id":"create-a-transifex-account","heading":"Create a Transifex Account"},{"id":"create-react-app","heading":"Create React App"},{"id":"install-dependencies","heading":"Install Dependencies"},{"id":"create-components","heading":"Create Components"},{"id":"run-the-website","heading":"Run the Website"},{"id":"localize-website","heading":"Localize Website","items":[{"id":"initialize-transifex","heading":"Initialize Transifex"},{"id":"add-translatable-strings","heading":"Add Translatable Strings"},{"id":"push-translation-strings","heading":"Push Translation Strings"},{"id":"change-languages","heading":"Change Languages"},{"id":"translating-more-text","heading":"Translating More Text"}]},{"id":"changing-layout","heading":"Changing Layout"},{"id":"benefits-of-transifex-native-react-sdk","heading":"Benefits of Transifex Native React SDK"},{"id":"conclusion","heading":"Conclusion"}]},"featureImageSharp":{"base":"How-to-Internationalize--i18n--a-React-App-with-Transifex-Native.jpg","publicURL":"/static/6862735adb4197b52f0aae64539e1079/How-to-Internationalize--i18n--a-React-App-with-Transifex-Native.jpg","imageMeta":{"width":1560,"height":876},"childImageSharp":{"fluid":{"base64":"data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAALABQDASIAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAAAAEDBf/EABQBAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhADEAAAAe3NRFH/xAAYEAADAQEAAAAAAAAAAAAAAAAAARIgIf/aAAgBAQABBQKimLuP/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPwE//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPwE//8QAGBAAAgMAAAAAAAAAAAAAAAAAAAEgMTL/2gAIAQEABj8CpmXH/8QAGBABAQADAAAAAAAAAAAAAAAAAREQIHH/2gAIAQEAAT8hVcRKLE7p/9oADAMBAAIAAwAAABDAD//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQMBAT8QP//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQIBAT8QP//EABoQAQEAAgMAAAAAAAAAAAAAAAERACAxUfD/2gAIAQEAAT8QAgaMpnpMepPXLT//2Q==","aspectRatio":1.7857142857142858,"src":"/static/6862735adb4197b52f0aae64539e1079/ea4ab/How-to-Internationalize--i18n--a-React-App-with-Transifex-Native.jpg","srcSet":"/static/6862735adb4197b52f0aae64539e1079/477ba/How-to-Internationalize--i18n--a-React-App-with-Transifex-Native.jpg 175w,\n/static/6862735adb4197b52f0aae64539e1079/06776/How-to-Internationalize--i18n--a-React-App-with-Transifex-Native.jpg 350w,\n/static/6862735adb4197b52f0aae64539e1079/ea4ab/How-to-Internationalize--i18n--a-React-App-with-Transifex-Native.jpg 700w,\n/static/6862735adb4197b52f0aae64539e1079/3055e/How-to-Internationalize--i18n--a-React-App-with-Transifex-Native.jpg 1050w,\n/static/6862735adb4197b52f0aae64539e1079/eff08/How-to-Internationalize--i18n--a-React-App-with-Transifex-Native.jpg 1400w,\n/static/6862735adb4197b52f0aae64539e1079/81a53/How-to-Internationalize--i18n--a-React-App-with-Transifex-Native.jpg 1560w","srcWebp":"/static/6862735adb4197b52f0aae64539e1079/89afa/How-to-Internationalize--i18n--a-React-App-with-Transifex-Native.webp","srcSetWebp":"/static/6862735adb4197b52f0aae64539e1079/9fca7/How-to-Internationalize--i18n--a-React-App-with-Transifex-Native.webp 175w,\n/static/6862735adb4197b52f0aae64539e1079/37a4e/How-to-Internationalize--i18n--a-React-App-with-Transifex-Native.webp 350w,\n/static/6862735adb4197b52f0aae64539e1079/89afa/How-to-Internationalize--i18n--a-React-App-with-Transifex-Native.webp 700w,\n/static/6862735adb4197b52f0aae64539e1079/78e7a/How-to-Internationalize--i18n--a-React-App-with-Transifex-Native.webp 1050w,\n/static/6862735adb4197b52f0aae64539e1079/03d34/How-to-Internationalize--i18n--a-React-App-with-Transifex-Native.webp 1400w,\n/static/6862735adb4197b52f0aae64539e1079/f5845/How-to-Internationalize--i18n--a-React-App-with-Transifex-Native.webp 1560w","sizes":"(max-width: 700px) 100vw, 700px"}}}}}]}},"pageContext":{"slug":"react-query-tutorial-for-beginners","prev":"what-are-events-in-javascript-and-how-to-handle-them","next":"beginners-guide-to-kubernetes-understand-the-basics","tag":"react","limit":3,"skip":0,"primaryTagCount":15,"collectionPaths":{}}},"staticQueryHashes":["1272700106","1676991999","2138873178","2546165603","2681841279","2938721187","293880488","3052966952","4156497161"]}