{"pageProps":{"data":{"title":"The easiest way to call APIs in React","date":"2018-08-29T06:00:00.000Z","description":"A React Hook that makes it super easy to request data from an API.","slug":"react-hooks-to-make-api-requests","locale":"en-US","dateFormatted":"Wednesday, August 29, 2018"},"content":{"compiledSource":"\"use strict\";\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\n/* @jsx mdx */\nvar layoutProps = {};\nvar MDXLayout = \"wrapper\";\n\nfunction MDXContent(_ref) {\n var components = _ref.components,\n props = _objectWithoutProperties(_ref, [\"components\"]);\n\n return mdx(MDXLayout, _extends({}, layoutProps, props, {\n components: components,\n mdxType: \"MDXLayout\"\n }), mdx(\"p\", null, \"A while ago I worked on a project that had a GraphQL API. On the frontend, I used a tool called \", mdx(\"a\", _extends({\n parentName: \"p\"\n }, {\n \"href\": \"https://www.apollographql.com/docs/react/\"\n }), \"React Apollo\"), \" to communicate with that API. One of the features I loved most about it was how you would get an object for your query that came with \", mdx(\"inlineCode\", {\n parentName: \"p\"\n }, \"loading\"), \", \", mdx(\"inlineCode\", {\n parentName: \"p\"\n }, \"error\"), \", and \", mdx(\"inlineCode\", {\n parentName: \"p\"\n }, \"data\"), \". These values would change over time during the life of a request. There's much more to Apollo and GraphQL, but that feature was one of my favorites.\"), mdx(\"p\", null, \"Now I'm working with a REST API. With React Hooks out, I knew I could easily and ergonomically reproduce this behavior. I ended up borrowing from the GraphQL terminology and created a hook I frequently use named \", mdx(\"inlineCode\", {\n parentName: \"p\"\n }, \"useQuery\"), \".\"), mdx(\"p\", null, mdx(\"inlineCode\", {\n parentName: \"p\"\n }, \"useQuery\"), \" is used to perform GET requests. It returns an object with the \", mdx(\"inlineCode\", {\n parentName: \"p\"\n }, \"loading\"), \", \", mdx(\"inlineCode\", {\n parentName: \"p\"\n }, \"error\"), \", and \", mdx(\"inlineCode\", {\n parentName: \"p\"\n }, \"data\"), \" properties.\"), mdx(\"p\", null, \"You would use it like this:\"), mdx(\"pre\", {\n \"className\": \"language-jsx\"\n }, mdx(\"code\", _extends({\n parentName: \"pre\"\n }, {\n \"className\": \"language-jsx\"\n }), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token keyword\"\n }), \"function\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token function\"\n }), mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token maybe-class-name\"\n }), \"App\")), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"(\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \")\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"{\"), \"\\n \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token keyword\"\n }), \"const\"), \" blogPosts \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token operator\"\n }), \"=\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token function\"\n }), \"useQuery\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"(\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"(\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \")\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token arrow operator\"\n }), \"=>\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token function\"\n }), \"fetch\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"(\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token string\"\n }), \"'/posts'\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \")\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \")\"), \"\\n\\n \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token keyword\"\n }), \"if\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"(\"), \"blogPosts\", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \".\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token property-access\"\n }), \"loading\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \")\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"{\"), \"\\n \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token keyword\"\n }), \"return\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token tag\"\n }), mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token tag\"\n }), mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token punctuation\"\n }), \"<\"), mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token class-name\"\n }), \"Loading\")), \" \", mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token punctuation\"\n }), \"/>\")), \"\\n \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"}\"), \"\\n\\n \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token keyword\"\n }), \"if\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"(\"), \"blogPosts\", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \".\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token property-access\"\n }), \"error\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \")\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"{\"), \"\\n \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token keyword\"\n }), \"return\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token tag\"\n }), mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token tag\"\n }), mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token punctuation\"\n }), \"<\"), mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token class-name\"\n }), \"Error\")), \" \", mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token attr-name\"\n }), \"error\"), mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token script language-javascript\"\n }), mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token script-punctuation punctuation\"\n }), \"=\"), mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token punctuation\"\n }), \"{\"), \"blogPosts\", mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token punctuation\"\n }), \".\"), mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token property-access\"\n }), \"error\"), mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token punctuation\"\n }), \"}\")), mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token punctuation\"\n }), \">\")), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token plain-text\"\n }), \"\\n }\\n\\n return (\\n \"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token tag\"\n }), mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token tag\"\n }), mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token punctuation\"\n }), \"<\"), mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token class-name\"\n }), \"Layout\")), mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token punctuation\"\n }), \">\")), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token plain-text\"\n }), \"\\n \"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token tag\"\n }), mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token tag\"\n }), mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token punctuation\"\n }), \"<\"), \"ul\"), mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token punctuation\"\n }), \">\")), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token plain-text\"\n }), \"\\n \"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"{\"), \"blogPosts\", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \".\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token property-access\"\n }), \"data\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \".\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token method function property-access\"\n }), \"map\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"(\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token parameter\"\n }), \"post\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token arrow operator\"\n }), \"=>\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"(\"), \"\\n \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token tag\"\n }), mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token tag\"\n }), mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token punctuation\"\n }), \"<\"), \"li\"), \" \", mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token attr-name\"\n }), \"key\"), mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token script language-javascript\"\n }), mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token script-punctuation punctuation\"\n }), \"=\"), mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token punctuation\"\n }), \"{\"), \"post\", mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token punctuation\"\n }), \".\"), mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token property-access\"\n }), \"id\"), mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token punctuation\"\n }), \"}\")), mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token punctuation\"\n }), \">\")), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token plain-text\"\n }), \"\\n \"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token tag\"\n }), mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token tag\"\n }), mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token punctuation\"\n }), \"<\"), \"a\"), \" \", mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token attr-name\"\n }), \"href\"), mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token script language-javascript\"\n }), mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token script-punctuation punctuation\"\n }), \"=\"), mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token punctuation\"\n }), \"{\"), \"post\", mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token punctuation\"\n }), \".\"), mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token property-access\"\n }), \"url\"), mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token punctuation\"\n }), \"}\")), mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token punctuation\"\n }), \">\")), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token plain-text\"\n }), \"\\n \"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"{\"), \"post\", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \".\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token property-access\"\n }), \"title\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"}\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token plain-text\"\n }), \"\\n \"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token tag\"\n }), mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token tag\"\n }), mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token punctuation\"\n }), \"\")), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token plain-text\"\n }), \"\\n \"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token tag\"\n }), mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token tag\"\n }), mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token punctuation\"\n }), \"\")), \"\\n \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \")\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \")\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"}\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token plain-text\"\n }), \"\\n \"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token tag\"\n }), mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token tag\"\n }), mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token punctuation\"\n }), \"\")), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token plain-text\"\n }), \"\\n \"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token tag\"\n }), mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token tag\"\n }), mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token punctuation\"\n }), \"\")), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token plain-text\"\n }), \"\\n )\\n}\\n\"))), mdx(\"p\", null, \"I love this because before you would have needed to use state and lifecycle methods in a Component class to implement the same behavior. Yes, we are still doing all that, but inside the \", mdx(\"inlineCode\", {\n parentName: \"p\"\n }, \"useQuery\"), \" hook. But this. This is very ergonomic. That's my favorite feature about it.\"), mdx(\"p\", null, \"Let's take a look at how it's implemented.\"), mdx(\"pre\", {\n \"className\": \"language-jsx\"\n }, mdx(\"code\", _extends({\n parentName: \"pre\"\n }, {\n \"className\": \"language-jsx\"\n }), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token keyword module\"\n }), \"import\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token maybe-class-name\"\n }), \"React\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token keyword module\"\n }), \"from\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token string\"\n }), \"'react'\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \";\"), \"\\n\\n\", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token keyword\"\n }), \"const\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token constant\"\n }), \"FETCH\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token operator\"\n }), \"=\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token string\"\n }), \"'FETCH'\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \";\"), \"\\n\", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token keyword\"\n }), \"const\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token constant\"\n }), \"SUCCESS\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token operator\"\n }), \"=\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token string\"\n }), \"'SUCCESS'\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \";\"), \"\\n\", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token keyword\"\n }), \"const\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token constant\"\n }), \"ERROR\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token operator\"\n }), \"=\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token string\"\n }), \"'ERROR'\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \";\"), \"\\n\\n\", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token keyword\"\n }), \"function\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token function\"\n }), \"reducer\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"(\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token parameter\"\n }), \"state\", mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token punctuation\"\n }), \",\"), \" action \", mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token operator\"\n }), \"=\"), \" \", mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token punctuation\"\n }), \"{\"), mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token punctuation\"\n }), \"}\")), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \")\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"{\"), \"\\n \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token keyword\"\n }), \"switch\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"(\"), \"action\", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \".\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token property-access\"\n }), \"type\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \")\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"{\"), \"\\n \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token keyword\"\n }), \"case\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token constant\"\n }), \"FETCH\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token operator\"\n }), \":\"), \"\\n \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token keyword\"\n }), \"return\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"{\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token spread operator\"\n }), \"...\"), \"state\", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \",\"), \" loading\", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token operator\"\n }), \":\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token boolean\"\n }), \"true\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \",\"), \" error\", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token operator\"\n }), \":\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token keyword null nil\"\n }), \"null\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"}\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \";\"), \"\\n \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token keyword\"\n }), \"case\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token constant\"\n }), \"SUCCESS\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token operator\"\n }), \":\"), \"\\n \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token keyword\"\n }), \"return\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"{\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token spread operator\"\n }), \"...\"), \"state\", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \",\"), \" data\", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token operator\"\n }), \":\"), \" action\", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \".\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token property-access\"\n }), \"payload\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \",\"), \" loading\", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token operator\"\n }), \":\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token boolean\"\n }), \"false\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"}\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \";\"), \"\\n \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token keyword\"\n }), \"case\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token constant\"\n }), \"ERROR\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token operator\"\n }), \":\"), \"\\n \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token keyword\"\n }), \"return\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"{\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token spread operator\"\n }), \"...\"), \"state\", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \",\"), \" error\", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token operator\"\n }), \":\"), \" action\", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \".\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token property-access\"\n }), \"payload\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \",\"), \" loading\", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token operator\"\n }), \":\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token boolean\"\n }), \"false\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"}\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \";\"), \"\\n \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token keyword module\"\n }), \"default\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token operator\"\n }), \":\"), \"\\n \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token keyword\"\n }), \"throw\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token keyword\"\n }), \"new\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token class-name\"\n }), \"Error\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"(\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token string\"\n }), \"'Unexpected action type.'\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \")\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \";\"), \"\\n \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"}\"), \"\\n\", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"}\"), \"\\n\\n\", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token keyword module\"\n }), \"export\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token keyword module\"\n }), \"default\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token keyword\"\n }), \"function\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token function\"\n }), \"useQuery\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"(\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token parameter\"\n }), \"query\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \")\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"{\"), \"\\n \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token keyword\"\n }), \"const\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"[\"), \"state\", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \",\"), \" dispatch\", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"]\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token operator\"\n }), \"=\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token maybe-class-name\"\n }), \"React\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \".\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token method function property-access\"\n }), \"useReducer\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"(\"), \"reducer\", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \",\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"{\"), \"\\n data\", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token operator\"\n }), \":\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token keyword nil\"\n }), \"undefined\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \",\"), \"\\n loading\", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token operator\"\n }), \":\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token boolean\"\n }), \"true\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \",\"), \"\\n error\", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token operator\"\n }), \":\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token keyword null nil\"\n }), \"null\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \",\"), \"\\n \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"}\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \")\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \";\"), \"\\n\\n \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token keyword\"\n }), \"async\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token keyword\"\n }), \"function\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token function\"\n }), \"fetchData\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"(\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \")\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"{\"), \"\\n \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token function\"\n }), \"dispatch\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"(\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"{\"), \" type\", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token operator\"\n }), \":\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token constant\"\n }), \"FETCH\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"}\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \")\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \";\"), \"\\n \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token keyword\"\n }), \"try\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"{\"), \"\\n \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token keyword\"\n }), \"const\"), \" data \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token operator\"\n }), \"=\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token keyword\"\n }), \"await\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token function\"\n }), \"query\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"(\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \")\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \";\"), \"\\n \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token function\"\n }), \"dispatch\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"(\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"{\"), \" type\", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token operator\"\n }), \":\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token constant\"\n }), \"SUCCESS\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \",\"), \" payload\", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token operator\"\n }), \":\"), \" data \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"}\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \")\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \";\"), \"\\n \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"}\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token keyword\"\n }), \"catch\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"(\"), \"error\", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \")\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"{\"), \"\\n \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token function\"\n }), \"dispatch\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"(\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"{\"), \" type\", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token operator\"\n }), \":\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token constant\"\n }), \"ERROR\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \",\"), \" payload\", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token operator\"\n }), \":\"), \" error \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"}\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \")\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \";\"), \"\\n \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"}\"), \"\\n \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"}\"), \"\\n\\n \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token maybe-class-name\"\n }), \"React\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \".\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token method function property-access\"\n }), \"useEffect\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"(\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"(\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \")\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token arrow operator\"\n }), \"=>\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"{\"), \"\\n \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token function\"\n }), \"fetchData\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"(\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \")\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \";\"), \"\\n \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"}\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \",\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"[\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"]\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \")\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \";\"), \"\\n\\n \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token keyword\"\n }), \"return\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"{\"), \"\\n data\", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token operator\"\n }), \":\"), \" state\", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \".\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token property-access\"\n }), \"data\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \",\"), \"\\n loading\", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token operator\"\n }), \":\"), \" state\", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \".\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token property-access\"\n }), \"loading\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \",\"), \"\\n error\", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token operator\"\n }), \":\"), \" state\", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \".\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token property-access\"\n }), \"error\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \",\"), \"\\n \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"}\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \";\"), \"\\n\", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"}\"), \"\\n\")), mdx(\"p\", null, \"It uses a reducer to change state. There are three actions: fetch start, fetch success, and fetch error. When \", mdx(\"inlineCode\", {\n parentName: \"p\"\n }, \"useQuery\"), \" is called, it starts fetching the data. It will automatically switch the state values as the fetch occurs.\"), mdx(\"p\", null, \"I've found that this has made my code simpler to read and faster to write. I hope you find it useful on your projects, too.\"));\n}\n\n;\nMDXContent.isMDXComponent = true;","renderedOutput":"

A while ago I worked on a project that had a GraphQL API. On the frontend, I used a tool called React Apollo to communicate with that API. One of the features I loved most about it was how you would get an object for your query that came with loading, error, and data. These values would change over time during the life of a request. There's much more to Apollo and GraphQL, but that feature was one of my favorites.

Now I'm working with a REST API. With React Hooks out, I knew I could easily and ergonomically reproduce this behavior. I ended up borrowing from the GraphQL terminology and created a hook I frequently use named useQuery.

useQuery is used to perform GET requests. It returns an object with the loading, error, and data properties.

You would use it like this:

function App() {\n  const blogPosts = useQuery(() => fetch('/posts'))\n\n  if (blogPosts.loading) {\n    return <Loading />\n  }\n\n  if (blogPosts.error) {\n    return <Error error={blogPosts.error}>\n  }\n\n  return (\n    <Layout>\n      <ul>\n        {blogPosts.data.map(post => (\n          <li key={post.id}>\n            <a href={post.url}>\n              {post.title}\n            </a>\n          </li>\n        ))}\n      </ul>\n    </Layout>\n  )\n}\n

I love this because before you would have needed to use state and lifecycle methods in a Component class to implement the same behavior. Yes, we are still doing all that, but inside the useQuery hook. But this. This is very ergonomic. That's my favorite feature about it.

Let's take a look at how it's implemented.

import React from 'react';\n\nconst FETCH = 'FETCH';\nconst SUCCESS = 'SUCCESS';\nconst ERROR = 'ERROR';\n\nfunction reducer(state, action = {}) {\n  switch (action.type) {\n    case FETCH:\n      return { ...state, loading: true, error: null };\n    case SUCCESS:\n      return { ...state, data: action.payload, loading: false };\n    case ERROR:\n      return { ...state, error: action.payload, loading: false };\n    default:\n      throw new Error('Unexpected action type.');\n  }\n}\n\nexport default function useQuery(query) {\n  const [state, dispatch] = React.useReducer(reducer, {\n    data: undefined,\n    loading: true,\n    error: null,\n  });\n\n  async function fetchData() {\n    dispatch({ type: FETCH });\n    try {\n      const data = await query();\n      dispatch({ type: SUCCESS, payload: data });\n    } catch (error) {\n      dispatch({ type: ERROR, payload: error });\n    }\n  }\n\n  React.useEffect(() => {\n    fetchData();\n  }, []);\n\n  return {\n    data: state.data,\n    loading: state.loading,\n    error: state.error,\n  };\n}\n

It uses a reducer to change state. There are three actions: fetch start, fetch success, and fetch error. When useQuery is called, it starts fetching the data. It will automatically switch the state values as the fetch occurs.

I've found that this has made my code simpler to read and faster to write. I hope you find it useful on your projects, too.

","scope":{}}},"__N_SSG":true}