<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Lukie Kang</title>
    <description>The latest articles on DEV Community by Lukie Kang (@neosaurrrus).</description>
    <link>https://dev.to/neosaurrrus</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F135623%2F926dfc75-3e04-40c0-acfd-339a329a0b16.png</url>
      <title>DEV Community: Lukie Kang</title>
      <link>https://dev.to/neosaurrrus</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/neosaurrrus"/>
    <language>en</language>
    <item>
      <title>JetBrains State of Developer Ecosystem</title>
      <dc:creator>Lukie Kang</dc:creator>
      <pubDate>Mon, 27 Nov 2023 10:57:58 +0000</pubDate>
      <link>https://dev.to/neosaurrrus/jetbrains-state-of-developer-ecosystem-52d8</link>
      <guid>https://dev.to/neosaurrrus/jetbrains-state-of-developer-ecosystem-52d8</guid>
      <description>&lt;p&gt;The &lt;a href="https://www.jetbrains.com/lp/devecosystem-2023/"&gt;JetBrains State of Developer Ecosystem&lt;/a&gt; dropped recently and well worth a read if you are involved in the developer space in some way and want to get a sense of how things are trending. &lt;/p&gt;

&lt;p&gt;A few things I thought notable were:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Rust and Typescript growing in popularity, it seems at the expense of languages like C++ and JavaScript respectively.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;91% of developers are male. In 2021 it was 93%. So I guess at that rate it will be 50/50 by 2066 or so!&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;46% of developers use GitHub Copilot. I suspect the % that admit that to their colleagues might be lower though 😉 In terms of AI, most developers feel it will help them rather than become a threat to their jobs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Three to Five years is the median range of professional coding experience. Curious where they go from that point, management perhaps? In an entirely unrelated note, 73% of developers also have experienced burnout...&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Top three job incentives for a developer are good hours, good pay and a job in which you feel you can achieve something. There seems to be a gender difference where women value more holidays and societal impact notably more than men.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;But there is &lt;em&gt;lots&lt;/em&gt; of interesting stuff in the report, its worth flicking through even if its to just challenge our own anecdotal experiences. Though I would love to have seen the results with a by country breakdown to see how that impacts the responses. I also wonder about the kinds of developer that will find the time to answer surveys and if that skews the results in a general direction.&lt;/p&gt;

</description>
      <category>developers</category>
      <category>survey</category>
    </item>
    <item>
      <title>Javascript Maps</title>
      <dc:creator>Lukie Kang</dc:creator>
      <pubDate>Tue, 14 Nov 2023 12:33:26 +0000</pubDate>
      <link>https://dev.to/neosaurrrus/javascript-maps-184</link>
      <guid>https://dev.to/neosaurrrus/javascript-maps-184</guid>
      <description>&lt;p&gt;The annoying thing about development is that there is always something you don't know about. The great thing about development is that there is always something new to learn. Life is all about perspectives. So the other day I came across this in a codebase:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const person = new Map()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And my reaction was... what is that Map thing, it isn't even an array?! &lt;/p&gt;

&lt;p&gt;So it turns out I have managed to avoid all knowledge of this JS data structure over my years with JS. I don't know how that happened but either I can feel inferior about it or I can do something about it. So I decided to take a little time out to learn about this Map data structure...&lt;/p&gt;

&lt;h2&gt;
  
  
  Whats a Map?
&lt;/h2&gt;

&lt;p&gt;So MDN would say:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The Map object holds key-value pairs and remembers the original insertion order of the keys. Any value (both objects and primitive values) may be used as either a key or a value.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Sounds like an object right? You are not wrong but there are some key (no nerdy pun intended) differences:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;In objects the key field must be an  string or as a symbol. Whereas in map it can be any datatype.&lt;/li&gt;
&lt;li&gt;Map is an instance of an object but an object is &lt;em&gt;not&lt;/em&gt; an instance of a map.&lt;/li&gt;
&lt;li&gt;Maps retain the order of the elements added. Objects...kinda have thier own order too but its complicated.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Creating a Map
&lt;/h2&gt;

&lt;p&gt;Whereas objects have object literal syntax: &lt;code&gt;const rabbit = {}&lt;/code&gt; as a handy shortcut. We have to use a constructor for a Map:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const empty = new Map()

const filled = new Map([
    [1, 'Apple'],
    [2, 'Banana'],
])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Accessing and Modifying Map properies
&lt;/h2&gt;

&lt;p&gt;For objects we can use dot or []'s to access properties. However for Maps we use a built-in get method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; const saladObj = {
    tomatoes: 5
    potatoes: 3
 }

 saladObj.tomatoes // 5

 const saladMap = new Map([
    ['tomatoes', 5],
    ['potatoes', 3]
 ])

 saladMap.get('tomatoes')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Unsuprisingly, changing maps involve a .set method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   saladMap.set('tomatoes', 10)

   saladMap.get('tomatoes') // 10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Other Handy Map methods:
&lt;/h1&gt;

&lt;h2&gt;
  
  
  .has
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; const saladMap = new Map([
    ['tomatoes', 5],
    ['potatoes', 3]
 ])

 saladMap.has('tomatoes') // true
 saladMap.has('beans') // false


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;## .size&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const saladMap = new Map([
    ['tomatoes', 5],
    ['potatoes', 3]
])

 saladMap.size // 2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;## .delete&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  saladMap.delete('tomatoes') // true
  saladMap.has('tomatoes') // false
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;## Iterating over a map&lt;/p&gt;

&lt;p&gt;Yup, you can forEach a map...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; const saladMap = new Map([
    ['tomatoes', 5],
    ['potatoes', 3]
])

saladMap.forEach((value, keys) =&amp;gt; {
    console.log(value, keys)
})

// 5 'tomatoes'
// 3 'potatoes'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also use a good old fashioned for...of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   for (const [key, value] of saladMap) {
    console.log(value, key)
   }

// 5 'tomatoes'
// 3 'potatoes'

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Map.groupBy
&lt;/h2&gt;

&lt;p&gt;This one is quite an interesting way of splitting out data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; const saladMap = new Map([
    ['tomatoes', 5],
    ['potatoes', 3]
])

const lowInventory = {needsMore: true};
const goodInventory = {needsMore: false};
const groupedSalad = Map.groupBy(saladMap, ([key, value]) =&amp;gt; value &amp;lt; 4 ? lowInventory : goodInventory)

groupedSalad.get(lowInventory) // [potatoes, 3]
groupedSalad.get(goodInventory) // [tomatoes, 5]

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The Object method Gotcha:
&lt;/h2&gt;

&lt;p&gt;Now you could try to add things like you would an object like &lt;code&gt;saladMap['tomatoes'] = 20&lt;/code&gt; however this would use the underlying Object logic and thus none of the map specific mehods would work on it as intended. And it is super confusing to boot:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    const mealMap = new Map()
    mealMap['beans'] = 10 // 10
    console.log(mealMap) // Map(0) {beans: 10, size: 0}
    mealMap['beans'] 10
    mealMap.has['beans'] // undefined
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Be very careful to avoid using object methods as it creates some weird results as you can see above.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why use it instead of an object?
&lt;/h2&gt;

&lt;p&gt;Objects are quick and easy to use, in most small cases they are probably fine but there is some notable occasions I can think of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;There is a clear order in how Maps are ordered.&lt;/li&gt;
&lt;li&gt;You can use any value for the key which might be handy&lt;/li&gt;
&lt;li&gt;There is more control and simplicity in the way the get/set/has/size works. Objects can be a little wild west and provide odd results in edge cases.&lt;/li&gt;
&lt;li&gt;A little easier to iterate over&lt;/li&gt;
&lt;li&gt;Faster when it comes to actions that involve a rapid additions and removal of key value pairs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However it is not natively supported in JSON so requires a little more effort if thats part of the workflow to be supported. &lt;/p&gt;

&lt;h2&gt;
  
  
  My takeaway on Maps.
&lt;/h2&gt;

&lt;p&gt;Overall, Maps are something I will add to my mental JS toolkit and reach for them in scenarios where they make sense as, in my mind, they are a bit more structured and predictable than regular Objects though I will have to play with them more to truly grok any pitfalls I have not considered. Browser support is also good with only the &lt;code&gt;.groupBy&lt;/code&gt; being a recent addition.  I want to benchmark that performance benefit as I am curious how quantifiable that would be but I certainly will bear maps in mind for complex algorithms using hashmaps.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>What's new in WCAG 2.2</title>
      <dc:creator>Lukie Kang</dc:creator>
      <pubDate>Mon, 13 Nov 2023 12:43:43 +0000</pubDate>
      <link>https://dev.to/neosaurrrus/whats-new-in-wcag-22-4n36</link>
      <guid>https://dev.to/neosaurrrus/whats-new-in-wcag-22-4n36</guid>
      <description>&lt;h2&gt;
  
  
  Whats a WCAG? What you on about?
&lt;/h2&gt;

&lt;p&gt;The WCAG (Web Content Accessibility Guidelines) is the guide for designing and building accessible applications. It has a number of success criteria over a number of categories and in 2023, there really is not much of an excuse to ignore these guidelines not just because it is the right thing to do but because a design that is accessible also is one that is very usable for &lt;em&gt;everyone&lt;/em&gt;. Most people would rather spend their cognitive capacity on thinking of kittens and food rather than trying hard to navigate their way through an application no matter how beautiful and cool it looks.&lt;/p&gt;

&lt;p&gt;As always its important to bear in mind that they are guidelines, not simply a set of checkboxes to hit, thinking through the lens of accessibility is what counts.  There is a system of A, AA, AAA to denote the level of accessibility reached. My shorthand for this is as follows:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;A - You have not made things unusable for people with accessibility needs. But you can do better.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;AA - You have done a decent job in making this a good experience, can you do better without huge effort though?&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;AAA - This is the gold standard, well done. Now see if your users with accessibility needs agree before you get too smug.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;While AA is a reasonable standard to hit in general, if you work on a governmental, utility or banking app, I would &lt;em&gt;strongly&lt;/em&gt; argue for greater levels of accessibility since access to those services is pretty much mandatory for all abilities in the modern age.&lt;/p&gt;

&lt;p&gt;The WCAG is freely available to read and follow so at least be aware of it though I admit it is not the most exciting of reads. So recently WCAG moved to version 2.2 in October 2023, so I was curious to see what new and exciting things this means for accessibility standards&lt;/p&gt;

&lt;h2&gt;
  
  
  So whats in 2.2? Is it a big deal?
&lt;/h2&gt;

&lt;p&gt;... &lt;em&gt;drumroll&lt;/em&gt; ... not really. There are 9 new success criteria introduced in this release and, in my opinion, they fall under the category of &lt;strong&gt;'Well, yes obviously it should do that....'&lt;/strong&gt;. However, having it officially in the WCAG is great for those of us that who have had to advocate pretty strongly for doing so before it was codified.&lt;/p&gt;

&lt;h2&gt;
  
  
  2.4.11/12 - Focus Not Obscured (AA/AAA)
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;2.4.11 - Ensure when an item gets keyboard focus, it is at least &lt;em&gt;partially&lt;/em&gt; visible.&lt;/p&gt;

&lt;p&gt;2.4.12 - Ensure when an item gets keyboard focus, it is &lt;em&gt;fully&lt;/em&gt; visible.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Keyboard focus is one of the pillars of accessibility access to a web app. If a user cannot use a mouse/finger then navigating via a keyboard matters. Hit tab a few times and you'll see what I mean. Having the 'focus ring' is essential in letting a user know where they are on the site, if it is hidden, the user has no idea where they are. Keep it visible.&lt;/p&gt;

&lt;p&gt;This one is quite commonly an issue simply because all the banners and pop-overs modern web sites have. If a site has a cookie prompt, newsletter sign up, or something like that, more often than not keyboard focus tends to suffer. While things have gotten a lot better recently (hello Dialog element) any time a banner/pop-over is introduced my accessibility-sense tingles. Be sure it tingles you too.&lt;/p&gt;

&lt;h2&gt;
  
  
  2.4.13 Focus Appearance (AAA)
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;2.4.13 - Use a focus indicator of sufficient size and contrast.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That focus ring I mentioned earlier? It might look cool if you made it a thin wispy off-white outline on your cool button but that really screws over people who actually need to see it. Make sure it is clearly visible. The WCAG goes on to say that it should be 2pm thick and with a contrast ratio of at least 3:1 between the pixels in the focused and unfocused states. I try to not get too much into the maths when thinking about accessibility, it should be clear and obvious, do that.&lt;/p&gt;

&lt;p&gt;One common gotcha here is that you might make a lovely clear blue focus indicator which is fine 99% of the time and thus it gets forgotten about... At some point someone introduces a blue button and.... suddenly that focus ring isn't as visible as you thought it was! In a nutshell, this Success Criteria isn't hard to hit but watch out for edge cases that need ot be handled in a different way.&lt;/p&gt;

&lt;h2&gt;
  
  
  2.5.7 Dragging Movements (AA)
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;For any action that involves dragging, provide a simple pointer alternative.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The WCAG would point out this is for the user that has a hand tremor and thus is unable to drag and drop. I would add that sometimes (e.g. on a phone screen) it is bloody annoying trying to drag and drop things into your UI. I know how cool your drop and drop looks and feels on your 32inch 4k screen and fancy mouse, but for others it is annoying at best, inaccessible at worst. Try using buttons to allow an alternative to drag and drag, your users will thank you.&lt;/p&gt;

&lt;h2&gt;
  
  
  2.5.8 Target Size (Minimum) (AA)
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Ensure targets meet a minimum size or have sufficient spacing around them.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This has happened to everyone I can guarantee it, especially on a mobile device. You have a bunch of icons, you tap on one and no, you actually hit another one because your finger is far bigger than the icon you were going for! Everyone is upset by this, not just those who might be impaired by pointing devices. Let your buttons breathe people, you you need to menu them away then do so, clutter is annoying for everyone. And yes I have been guilty of squeezing 'just one more icon' into a space that really shouldn't take any more. It happens but lets do better!&lt;/p&gt;

&lt;h2&gt;
  
  
  3.2.6 Consistent Help (A)
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Put help in the same place when it is on multiple pages.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I am of the generation that stubbornly refuses to click on help in any circumstance. I am also not a good role model. For others, a help option on an app is a first point of call to know what to do. It is fairly obvious but if you have a help functionality, make sure it is in a consistent place on the page to avoid confusing people. This is also just good design in general however, keeping things in a consistent place makes it easier to understand and fly through your lovingly crafted user journeys.&lt;/p&gt;

&lt;p&gt;A gotcha here is the aforementioned banners and pop-overs, it does no good to have the help function in the same place but occasionally it gets hidden by other elements. &lt;/p&gt;

&lt;h2&gt;
  
  
  3.3.7 Redundant Entry (A)
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Don't ask for the same information twice in the same session.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The WCAG will say that this helps those with cognitive disabilities who have difficulty remembering what they entered before. I would add, it bloody annoying to keep on providing info I entered before. I don't think this one warrants much discussion as if you are not trying to make your input processes as frictionless as possible for everyone then we probably need to chat about more basic things than WCAG.&lt;/p&gt;

&lt;h2&gt;
  
  
  3.3.8/9 Accessible Authentication (Minimum/Enhanced) (AA/ AAA)
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;3.3.8 - Don’t make people solve, recall, or transcribe something to log in. (AA)&lt;/p&gt;

&lt;p&gt;3.3.9 - Don’t make people recognize objects or user-supplied images and media to login. (AAA)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Oh, now I have saved the best till last. I love it when one important principle (accessibility) is rubbing shoulders with another (security), so now you have decide if you want a secure app or an accessible app. Pick one.... Ok, ok, it isn't actually so bad, the key things to bear in mind here for are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Allow password managers and autocomplete to work to reduce memory need&lt;/li&gt;
&lt;li&gt;Allow copy and paste to reduce cognitive burden&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you are going to have a cognitive function test (i.e. click all the 'motorcycles' captcha things) then:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Allow an alternative authentication method that avoids a reliance on cognitive function (easier)&lt;/li&gt;
&lt;li&gt;Support is provided to assist the user in completing the cognitive function test (more risky)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Since most people reading this are not coding up their own captcha tooling this has already been addressed for the most part by providers. But certainly its worth being mindful of this as captchas continue to be more sophistated/harder to do.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;I stand by my original view that these success criteria should be obvious to those of us who care about a great UX in general. But having it in the WCAG allows us to make the case for these things far more easily when dealing with people who cannot conceive of things existing outside of checkboxes and metrics... you know you have met those people before.&lt;/p&gt;

&lt;p&gt;The true hotness to get excited about is version 3.0 which is still very much a work in progress. If you are interested in the future of accessibility, or if you got bones to pick about the WCAG then why not &lt;a href="https://www.w3.org/WAI/about/participating/#participating-in-guidelines-and-groups"&gt;get involved&lt;/a&gt; ? &lt;/p&gt;

</description>
      <category>a11y</category>
      <category>web</category>
    </item>
    <item>
      <title>A Very Rough Guide to solving Coding Challenges</title>
      <dc:creator>Lukie Kang</dc:creator>
      <pubDate>Wed, 08 Nov 2023 12:15:23 +0000</pubDate>
      <link>https://dev.to/neosaurrrus/a-very-rough-guide-to-solving-coding-challenges-3362</link>
      <guid>https://dev.to/neosaurrrus/a-very-rough-guide-to-solving-coding-challenges-3362</guid>
      <description>&lt;p&gt;This post is all about how I break down a coding challenge. How I think might be brilliant for you, it might just make you angry. Who knows, but we know we can always rely on the Internet to offer constructive feedback and support!&lt;/p&gt;

&lt;h1&gt;
  
  
  Be confident in your toolkit: Data structures and Algorithms.
&lt;/h1&gt;

&lt;p&gt;Data structures are different ways of collecting information, an array/list vs an object/dictionary and another douzen or so common ones. Algorithms are a set of steps to accomplish a certain task, often working with one data structure and working it into another one. You need both of these to be in your mental toolbox.&lt;/p&gt;

&lt;p&gt;Explaining whats recommended in that toolbox is worth a blog post of its own but the takeaway is that you need the toolkit. Sure, some people are better at solving problems than others, but more often its more a case of just not having the right tool in your mental toolkit. &lt;/p&gt;

&lt;h1&gt;
  
  
  Problem Solving Steps
&lt;/h1&gt;

&lt;ol&gt;
&lt;li&gt;Breathe&lt;/li&gt;
&lt;li&gt;Understand the problem&lt;/li&gt;
&lt;li&gt;Explore Concrete Examples&lt;/li&gt;
&lt;li&gt;Break it down&lt;/li&gt;
&lt;li&gt;Solve/Simplify&lt;/li&gt;
&lt;li&gt;Look back and refactor&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  0. Breathe
&lt;/h1&gt;

&lt;p&gt;Some people can tap into their 'problem-solving' brain without too much issue in a high-pressure situation. Others, like me, go into panic mode and make it really hard to think. I can &lt;em&gt;barely type&lt;/em&gt; in such situations let alone access 'problem-solving' mode. For &lt;em&gt;me&lt;/em&gt; it works to take 10 seconds or so to acknowlege the situation &lt;em&gt;is&lt;/em&gt; hard and remind myself to just be methodical and see what happens with some long deep breaths. I think it is my ADD brain trying to run all the problem solving steps at the same time causing a confusing mess as a result. Step by step, thats all you need though thats easier said than done.&lt;/p&gt;

&lt;p&gt;Practice solving problems under some kind of pressure at home, be it a timer or on a screen recording... it does get easier. &lt;/p&gt;

&lt;h1&gt;
  
  
  1. Figure out the problem
&lt;/h1&gt;

&lt;p&gt;Before we can solve the problem, we must first need to understand what we need to do. Investigate the requirements and ask questions, resist the urge to jump to code, there is always a hidden gotcha to watch for.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Can you restate the problem in your own words? &lt;/li&gt;
&lt;li&gt;What are the inputs that go into the problem?&lt;/li&gt;
&lt;li&gt;what are the outputs that should come from the solution to the problem problem? What does it look like?&lt;/li&gt;
&lt;li&gt;Can the outputs be figured out from the inputs? (if you can figure that out at this stage)&lt;/li&gt;
&lt;li&gt;How can I label the important pieces of data that are a part of the problem? What matters here to solve the problem?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you can't do the above before leaping into code. It is likely going to give you a bad day! &lt;/p&gt;

&lt;p&gt;Another tip, I think in diagrams: Drawing out boxes and arrows to map out what I think we are trying to do, you might find this may help you too. If I can put the &lt;em&gt;what&lt;/em&gt; onto paper I often find it gives me more room in my head to focus on the &lt;em&gt;how&lt;/em&gt;. Do it slowly and well, you don't want to be trying to decipher an unintelligble squiggle later on! (Ask me how I know...)&lt;/p&gt;

&lt;h1&gt;
  
  
  2. Come Up With Examples
&lt;/h1&gt;

&lt;p&gt;Basically plug in some default values to see what you expect. These are effectivley simple log machines: given a particular input what is our output?&lt;/p&gt;

&lt;p&gt;You shouldnt do this willy-nilly, but consider the following scenarios, in a designing a function that just adds two numbers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Simple examples (2,2)&lt;/li&gt;
&lt;li&gt;Complex Example ( 20000.54 + 200000000.32 )&lt;/li&gt;
&lt;li&gt;Empty inputs ( 2, )&lt;/li&gt;
&lt;li&gt;Invalid Inputs (2, "fish")&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Also consider how the output should be presented. Should it just be the value? does it need rounding? does it need to come back in a string etc?&lt;/p&gt;

&lt;p&gt;Playing around with examples, is an extension of understanding the problem and might help uncover some key things to pay attention to when building your solution. This i s where having your mental toolkit polished and ready to go is so important.&lt;/p&gt;

&lt;p&gt;In my experience, people are very good at telling you what they want, but even better at thinking they have given you all the details you need to deliver. &lt;em&gt;Don't be afraid to ask those dumb questions as it will save you time in the long run!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Final point, we don't have to address every edge case to focus on the solving the core problem, acknowledging that it exists is important however and if it can be solved later then its generally best to have something that 90% works you can tweak later than getting bogged down trying to solve everything perfectly...which leads to. &lt;/p&gt;

&lt;h1&gt;
  
  
  Break it Down
&lt;/h1&gt;

&lt;p&gt;This is all about the How. You should have a decent idea on WHAT you are trying to do, WITH what values. Now lets look at the HOW.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;4 easy problems is better than 1 hard problem.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;So lets break the problem down into smaller pieces, outlining the basic steps you need to take. This will give you a framework to write your code without worrying about the code.&lt;/p&gt;

&lt;p&gt;Using comments to outline your approach is a good way to do this.&lt;/p&gt;

&lt;p&gt;You don't have to be wedded to what you put down. You might start with one comment, and break that down further. The smaller the pieces, the easier the code for that is to write.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;addNumbers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="c1"&gt;//check if a and b are numbers&lt;/span&gt;
        &lt;span class="c1"&gt;//if not number, handle the error&lt;/span&gt;
    &lt;span class="c1"&gt;//add a and b together&lt;/span&gt;
    &lt;span class="c1"&gt;//return string that presents the result correctly with rounding.&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is really handy for an observer (say, an interviewer) to know what you are thinking about when you are code.&lt;/p&gt;

&lt;h1&gt;
  
  
  Lets solve it, or make it simpler!
&lt;/h1&gt;

&lt;p&gt;So now that you have an idea of HOW you can do it, try and solve it! If you can, great! but if you can't... try to solve a simplified version of it.&lt;/p&gt;

&lt;p&gt;Obviously you want to solve it. However the logic behind simplfying is that it lets you begin exploring the issue and may trigger some further understanding.&lt;/p&gt;

&lt;p&gt;When you are simplfying you can use the following steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Identify the tricky part of what you are trying to do.&lt;/li&gt;
&lt;li&gt;Ignore that tricky part&lt;/li&gt;
&lt;li&gt;Swap it with an easy part&lt;/li&gt;
&lt;li&gt;Then explore the differences between the two.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Some examples of simplifying:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If you have an array to iterate through, just try and make a solution for just the first element.&lt;/li&gt;
&lt;li&gt;If you can't recall a method (for rounding a number, say) just refer to it in your comments and see if you can research it later (if you can't figure it out in a minute or two)&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Look back and Refactor, I heard you say...
&lt;/h1&gt;

&lt;p&gt;Ok, so you have got your function working. Good job! But, unless you are under a really tight deadline, you aint quite done yet.&lt;/p&gt;

&lt;p&gt;Your first successful attempt is rarely your best attempt so there are some things you can ask yourself in order to improve what you have done.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Can you check it works for all inputs? See Step 2 earlier.&lt;/li&gt;
&lt;li&gt;Can you get to the answer to a different way, what other ways are out there?&lt;/li&gt;
&lt;li&gt;Can you understand it when you look at it? Can you make it clearer and neater?&lt;/li&gt;
&lt;li&gt;Does this solve or help with another problem?&lt;/li&gt;
&lt;li&gt;Can you improve the performance of your solution?&lt;/li&gt;
&lt;li&gt;Can you simplify it in other ways?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Those points may be more or less relavent depending on what you are doing.&lt;/p&gt;

&lt;h1&gt;
  
  
  So lets take what we have learnt...
&lt;/h1&gt;

&lt;p&gt;Lets apply our new found problem solving plan to a simple problem your imaginary boss/interviewer gives you:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Write a function that will remove specified numbers from an array of numbers&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Understand the problem&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;We can restate the problem as &lt;em&gt;Check an array for certain numbers and remove them&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We can learn the following from our boss:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The numbers we need to check for will be provided in an array.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The output should be an array of numbers&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The key pieces of information are the source array, the array of numbers we need to check against and the output array. How these interact is key to solving this.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;Come up with Examples&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You can jot down some arrays to visualise what the function should do. First you come up with the simplest version to help you see the big picture:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Input 1 - sourceArray = [1,2,3,4]&lt;/code&gt;&lt;br&gt;
&lt;code&gt;Input 2 - checkArray = [1,3]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Function does something&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Output Array = [2,4]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Secondly you should consider what would constitute a complex example, at this point you should ask your boss what values are expected. Especially floating points and huge numbers. Luckily, she tells you no to both but the arrays could have over a thousand elements.&lt;/p&gt;

&lt;p&gt;So your complex example could have a thousand elements in both the sourceArray and the numbers you are checking on....don't write it out.&lt;/p&gt;

&lt;p&gt;Lastly, figure out if there is any need to deal with blank or non-integer values. For the same of this blog post, we are assuming she says no, its all nice simple integers. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Break it Down!&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now you should have a decent idea of what the solution should do and roughly what to expect in terms of inputs you should be able to sketch out an initial approach to the solution.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;removeNumbers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sourceArray&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;checkArray&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="c1"&gt;//1. Get the first number in the checkArray&lt;/span&gt;
    &lt;span class="c1"&gt;//2. check each element in source array for this number&lt;/span&gt;
    &lt;span class="c1"&gt;//3. where we find it, remove the element&lt;/span&gt;
    &lt;span class="c1"&gt;//4. Repeat for the next number in the checkArray&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If its really easy code feel free to write it, otherwise just stating in plain english should suffice for now. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Solve or Simplify&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Ok, so you are happy with the initial approach, now you can take your skeleton and put some tasty flesh (or code) onto it.&lt;/p&gt;

&lt;p&gt;Based on our approach above we decide to first build the algorithm as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;removeNumbers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sourceArray&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;checkArray&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;//4. Loop for the next number in the checkArray&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;checkArray&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;//1. Get the first number in the checkArray&lt;/span&gt;
        &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;numberToCheck&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;checkArray&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
        &lt;span class="c1"&gt;//2. check each element in source array for this number, starting with 0&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;j&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;j&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;=&lt;/span&gt;&lt;span class="nx"&gt;sourceArray&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;j&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;//3. where we find it, remove the element&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;numberToCheck&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;sourceArray&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;j&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nx"&gt;sourceArray&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;splice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;j&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  
                &lt;span class="nx"&gt;j&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;sourceArray&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You plug in a few test values and it seems to give you the right answer!&lt;/p&gt;

&lt;p&gt;Are we done? Lets do this Choose your own Adventure style!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you said Yes&lt;/strong&gt;&lt;br&gt;
You show your boss the input and outputs working. She is happy enough, but too busy to look too closely. You go on to throw together a number of other functions on the system. At some point this will probably catch up to you... but for now you have survived.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you said No&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You furrow your brow and realise there might be a better way of doing this, you roll up your sleeves and look again at the code...&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Reflect and Refactor&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Well done, a little extra time spent trying to improve your code is well spent.&lt;/p&gt;

&lt;p&gt;By playing around with it for a few minutes you decide:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Those ForLoops are hard to read, as you are dealing with arrays you think to use &lt;code&gt;ForEach&lt;/code&gt; and &lt;code&gt;Some&lt;/code&gt; methods instead.&lt;/li&gt;
&lt;li&gt;Now its clearer you probably don't need those comments for every part.&lt;/li&gt;
&lt;li&gt;You recall that its not a good idea to mutate the original array so you use a new array for your results.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;removeNumbers2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sourceArray&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;checkArray&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;newArray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
   &lt;span class="nx"&gt;sourceArray&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sourceNum&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;checkArray&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;checkNum&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;  &lt;span class="nx"&gt;sourceNum&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;checkNum&lt;/span&gt;&lt;span class="p"&gt;)){&lt;/span&gt; &lt;span class="c1"&gt;//check if the Source array element is NOT found in the checkArray&lt;/span&gt;
            &lt;span class="nx"&gt;newArray&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sourceNum&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
   &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;newArray&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that still works but is a little more robust and clearer. If you were to think about it some more, you would probably kick yourself for not using the &lt;code&gt;filter&lt;/code&gt; method in some way.&lt;/p&gt;

&lt;p&gt;The point is that a little time reviewing your code can make a difference, but it might take a couple of iterations to get to 'perfection'&lt;/p&gt;

&lt;p&gt;Now you note I didn't talk about the performance of our example much. There are certain patterns you should look out for when trying to look for efficiencies. That is also a topic for another time because really if you can solve the problem, that is worth appreciating as an accomplishment in and of itself. Perfection can, and really should, wait...&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Dipping my Toes into Typescript in React</title>
      <dc:creator>Lukie Kang</dc:creator>
      <pubDate>Mon, 08 Feb 2021 10:41:57 +0000</pubDate>
      <link>https://dev.to/neosaurrrus/dipping-my-toes-into-typescript-in-react-44nc</link>
      <guid>https://dev.to/neosaurrrus/dipping-my-toes-into-typescript-in-react-44nc</guid>
      <description>&lt;p&gt;I recently attended a webinar by Roy Derks and it inspired me to get into type systems since they are an awfully dry subject to try and get the concept and usefulness across.&lt;/p&gt;

&lt;p&gt;Type systems are getting more popular in the Javascript world with Typescript by far the most popular as we begin 2021. With React being pretty popular with me, I wanted to get into Typescript via the world I am familiar with. And write about the landmines I step on along the way! By the way, I am assuming you know a little bit about React but nothing about Typescript.&lt;/p&gt;

&lt;p&gt;In this post I will look at:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What is Typescript&lt;/li&gt;
&lt;li&gt;What Types are&lt;/li&gt;
&lt;li&gt;Starting a  React App with Typescript support built-in&lt;/li&gt;
&lt;li&gt;Our first TSX Component, and Typescript error.&lt;/li&gt;
&lt;li&gt;Common Types in Typescript&lt;/li&gt;
&lt;li&gt;Examples in Functions, Events and Children&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The post ends fairly abruptly. As I often do, this is just a post to whet the appetite and get the ball rolling to get into things enough to research when using it for other things. Sound fair? Ok let's go...&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Typescript, how is it different to use  Javascript?
&lt;/h2&gt;

&lt;p&gt;Typescript is known as a superset of Javascript. In other words, it adds extra functionality on top of Javascript. &lt;em&gt;Javascript with Types&lt;/em&gt; is a good, if simplified, 3-word explanation.&lt;/p&gt;

&lt;p&gt;The nice thing about Typescript is that it has a compile step which turns it back into Javascript. So that means it is quite easy to dip your toe into Typescript without having to do anything radically different to writing Javascript.&lt;/p&gt;

&lt;p&gt;Having a compile step does mean that it has to be run before your browser can make sense of it. If you have been using frameworks like React however, this shouldn't be an alien concept.&lt;/p&gt;

&lt;p&gt;Typescript files have a &lt;code&gt;.ts&lt;/code&gt; extension as opposed to &lt;code&gt;js&lt;/code&gt; in case you stumble across them. In React, components will use the &lt;code&gt;tsx&lt;/code&gt; extension.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ok, sooo... whats the Type in Typescript all about?
&lt;/h2&gt;

&lt;p&gt;Programming languages come in two flavours. Statically typed or dynamically typed. Dynamically typed languages like Javascript don't make it something we need to consider, at least when writing the code initially &lt;/p&gt;

&lt;p&gt;In statically typed languages we say what datatype it is before running it (i.e Age is an integer, Name is a string). In Javascript we never do that so we can do things like this without a thought:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;another_age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;12yo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;book&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1984&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;year_of_birth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1984&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;JS doesn't ask you what datatype you intended, which is nice except then it takes that decision itself which leads to some interesting results. In the example above, adding two of those variables can result in a variety of results. With Javascript, we don't see these errors till the code is running, and is so much harder to debug&lt;/p&gt;

&lt;p&gt;Static typing allows us to catch errors much easier. If something is not defined with a type, or against its type definition. It gets thrown up at the compile step allowing us to address it before it gives us a headache later on.&lt;/p&gt;

&lt;p&gt;There is more to TS than just that but let's keep it simple for now.&lt;/p&gt;

&lt;h2&gt;
  
  
  "OK, lets get started with it"
&lt;/h2&gt;

&lt;p&gt;Let's get started with installing create-react-app with typescript installed.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npx create-react-app my-app --template typescript&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If you already have an existing create-react-app app you want to convert to use typescript you can see see the relevant &lt;a href="https://create-react-app.dev/docs/adding-typescript/"&gt;create react app guide&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you rolled your React app without Create-React-App, then there are too many possibilities to advise.&lt;/p&gt;

&lt;p&gt;Anyhow after a fresh new Create-React-App, you will notice that the typical starter JS files &lt;code&gt;Index&lt;/code&gt; and &lt;code&gt;App&lt;/code&gt; now have the TSX extension. You will also see some other new TS files. It's slightly disturbing seeing something familiar become slightly weird but we will get there../&lt;/p&gt;

&lt;p&gt;It's important to note, it will still allow us to use regular JS components if we wanted to (say if you have old components you want to migrate to TS later). If you check the &lt;code&gt;tsconfig.json&lt;/code&gt; in the root of the application, there is an option to change this called 'allowJs'. As I said earlier, once you have Typescript setup it doesn't mean you have to always use it... but yeah, this would be a pointless blog post if I didn't! Quick note: If you are converting JS files to JSX files you may need to restart the server to get React to realise it.&lt;/p&gt;

&lt;p&gt;Speaking of which, you can start the server as you would any create-react-app with an &lt;code&gt;npm start&lt;/code&gt; or &lt;code&gt;yarn start&lt;/code&gt; depending on which one you like using.&lt;/p&gt;

&lt;h2&gt;
  
  
  Our first TS component, let's do proper props.
&lt;/h2&gt;

&lt;p&gt;We can create a component as we would otherwise but this time rocking the new &lt;code&gt;tsx&lt;/code&gt; extension:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;OurFirstTSXComponent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Hey&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="nx"&gt;is&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;Typescript&lt;/span&gt;&lt;span class="o"&gt;!&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That shouldn't be too shocking. If you are running the React server you should see the component works as you'd hope. Regular JS is fine till we start using some of the things Typescript cares about. Like, say, props...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;OurFirstTSXComponent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;isMorning&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Hey&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="nx"&gt;is&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;Typescript&lt;/span&gt;&lt;span class="o"&gt;!&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h3&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Hello&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h3&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;isMorning&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h3&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Good&lt;/span&gt; &lt;span class="nx"&gt;Morning&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h3&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;}
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you have the server running, this is the point Typescript starts to get interesting.&lt;/p&gt;

&lt;p&gt;Basicially we have two props, a string and a boolean...and our first Typescript error! &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Type '{}' is missing the following properties from type '{ username: any; isMorning: any; }': username, isMorning&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Which is it a polite way of saying you haven't said what those props are! Note that the linting rules will do its best to highlight where issues exist. Anyhow let's sort that out in three steps:&lt;/p&gt;

&lt;p&gt;Step 1: Define our props. &lt;/p&gt;

&lt;p&gt;In the component, let's say what props we are going to have.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Props&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;//'Props' is an arbitrary choice &lt;/span&gt;
    &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;isMorning&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 2: Assign the props given to that Props object.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;OurFirstTSXComponent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;isMorning&lt;/span&gt;&lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;Props&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 3: Actually give the component props in the parent component. Since we said it was going to have &lt;code&gt;username&lt;/code&gt; and &lt;code&gt;isMorning&lt;/code&gt; props, we better provide them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;OurFirstTSXComponent&lt;/span&gt; &lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;tom&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;isMorning&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="sr"&gt;/&amp;gt; /&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;really&lt;/span&gt; &lt;span class="nx"&gt;regret&lt;/span&gt; &lt;span class="nx"&gt;that&lt;/span&gt; &lt;span class="nx"&gt;component&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To those of you who are used to Proptypes, that should not be too shocking. But as we have just seen, typescript tells you if there is an issue on compile which ensures it gets dealt with.&lt;/p&gt;

&lt;h2&gt;
  
  
  What if a prop is Optional?
&lt;/h2&gt;

&lt;p&gt;Short answer, using ? makes the prop optional:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Props&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;isMorning&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In regular React, props are generally optional which, if you are like me, means I often include things that later on I don't need. Typescript, as you have just seen, makes us very explicit about the props we want and optional props are now the exception which is probably for the best.&lt;/p&gt;

&lt;h2&gt;
  
  
  And what about default Props?
&lt;/h2&gt;

&lt;p&gt;Thats a fair point. As a quick reminder, default props in react allows us to ...well, set a default value for our props:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;OurFirstTSXComponent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;defaultProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Alice&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="na"&gt;isMorning&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In Typescript we can use classic JS ways of setting default values inside of Parameters:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;export const OurFirstTSXComponent = ({username = "Alice", isMorning = false }) =&amp;gt; {&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;Easy! If you don't do anything else with Typescript you already are getting some benefits. But sorting our props was just paddling in the lake of Typescript so lets get swimming into some deeper waters and look more closely at types and how they relate to functions.&lt;/p&gt;

&lt;h1&gt;
  
  
  So what are some types in Typescript?
&lt;/h1&gt;

&lt;p&gt;This probably won't shock you but types are the foundation of Typescript, we touched on a few when looking at props. It's good to get more familiar with at least the ones you use in regular JS. &lt;/p&gt;

&lt;h2&gt;
  
  
  Common Garden Types
&lt;/h2&gt;

&lt;p&gt;First of all let's cover off the ones that should not need explaining:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;String&lt;/li&gt;
&lt;li&gt;Number (also bigInts)&lt;/li&gt;
&lt;li&gt;Boolean&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But wait? How do you say a variable is a string exactly? Well this is the syntax you will see a lot when it comes to Typescript:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;let isHappy: boolean = false;&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;As opposed to a two-step process with &lt;code&gt;let isHappy = false&lt;/code&gt; there are three steps which I call &lt;code&gt;assignment-type-value&lt;/code&gt;. The typescripty bit is the &lt;code&gt;: boolean&lt;/code&gt; in the middle that says what type we want the variable to be.&lt;/p&gt;

&lt;h2&gt;
  
  
  New Types on the Block
&lt;/h2&gt;

&lt;p&gt;Here are a few more basic types you might come across that are found in Typescript:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Arrays&lt;/strong&gt; can be declared stating what you expect them to contain: &lt;code&gt;let scores: number[] = [1,2,3,4]&lt;/code&gt; is an array of numbers.&lt;br&gt;
&lt;strong&gt;Tuples&lt;/strong&gt; are Arrays' more formal sibling and allows you express an array of fixed length where the types are known:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="nx"&gt;product&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Shoes&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;34&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;//will work&lt;/span&gt;
&lt;span class="nx"&gt;product&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Shoes&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;34&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;//will NOT work&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Enums are common in other languages like C#, which basically allows you to map a word to a number. In other words, making it easier for a human to assign:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;emum&lt;/span&gt; &lt;span class="nx"&gt;Size&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;Small&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;Medium&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;Large&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Size&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;medium&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So we can call the text value by calling it like an array so &lt;code&gt;let sizeName: string = Size[1]&lt;/code&gt; would map to Medium.&lt;/p&gt;

&lt;p&gt;As quick aside,  &lt;strong&gt;unions&lt;/strong&gt; which are something I will go into at a later point but one quick takeaway is we something like this to specify the valid parameters for that variable.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;meal: "breakfast"|"lunch"|"dinner"&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Which is cool.&lt;/p&gt;

&lt;h3&gt;
  
  
  Weird metaphysical types
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Unknown&lt;/strong&gt; is what it says when we don't know what it is. If its something provided by the user for example. We should probably know what the vast majority of our inputs are if we are coding them ourselves!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Any&lt;/strong&gt; is any type, and effectively is doing what JS has been doing. Why use it? Sometimes it might genuinely be needed or as part of a hybrid TS/JS/3rd party library situation. Just try not to lean on it too much!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Void&lt;/strong&gt; is like the opposite of any. It won't have any type. This is typically used in functions where it won't be returning anything explicitly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Never&lt;/strong&gt; is a weird one. Basically saying it will never exist. Typically in functions that do not complete and so won't be able to return anything (undefined or otherwise)&lt;/p&gt;

&lt;h2&gt;
  
  
  Function Types
&lt;/h2&gt;

&lt;p&gt;Assigning types to variables is fairly simple based on the above but what about using them with functions? Let's take a better look at that!&lt;/p&gt;

&lt;p&gt;Let's take a basic button component which is fed a function via props:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Hello&lt;/span&gt;&lt;span class="o"&gt;!&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;//In the parent component we can have something like:&lt;/span&gt;

&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Button&lt;/span&gt; 
    &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;How is it going?&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}}&lt;/span&gt;
&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Linting rules for typescript will be pointing out that because we have not specified the output of the function, it is considered an &lt;em&gt;Any&lt;/em&gt; type. This is not good typescripting so let's fix it up.&lt;/p&gt;

&lt;p&gt;As we are not returning something we can use that mysterious &lt;code&gt;void&lt;/code&gt; type, in a similar format to before.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Props&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;  &lt;span class="c1"&gt;// or...&lt;/span&gt;
    &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;:(&lt;/span&gt;&lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;
    &lt;span class="c1"&gt;// if, for example, we were passing in a string value to the function&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;Props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;//etc&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is a bunch of ways we can define functions in TS but this is the most typical approach.&lt;/p&gt;

&lt;h2&gt;
  
  
  Handling React Events in Typescript
&lt;/h2&gt;

&lt;p&gt;Events, in this case, relate to interacting with the component in some way. &lt;/p&gt;

&lt;p&gt;In JS world we just specify &lt;code&gt;e&lt;/code&gt; and off we go:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleClick&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;//stuff&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In typescript it will complain that the event hasnt been specified so we can do something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Props&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MouseEvent&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ChangeEvent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;//Mouse Event  &lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But this is just saying we have a mouseevent, Its good to be specific with typescript for it to offer the best advice as you code. So we can say especially it is, for example, a form element, or button element:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Props&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MouseEvent&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;HTMLButtonElement&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ChangeEvent&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;HTMLFormElement&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;//Mouse Event  &lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are a whole bunch of Events and Elements you can specify. VSCode's IntelliSense is a good way fo figuring out what you should reach for a given event.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dealing with Child Props
&lt;/h2&gt;

&lt;p&gt;Simple props are easy enough to plan for as we did earlier. But what about children of the component. For example, what if we had a button with an image tag:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;   &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Button&lt;/span&gt; 
    &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;preventDefault&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;How is it going?&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;img&lt;/span&gt; &lt;span class="nx"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;something&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;somewhere.png&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If its just a string, from a &amp;lt; H1 &amp;gt; instead of an &amp;lt; IMG &amp;gt; we could just explicitly say the component has a child that returns a string:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Props&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;children&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MouseEvent&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;HTMLButtonElement&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;//Mouse Event  &lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; 

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However if we were using more complex or unknown children, this can start getting hard to manage in the props. This is where we have a little help in the form of refactoring our component to use&lt;code&gt;React.fc&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;FC&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Props&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Hello&lt;/span&gt;&lt;span class="o"&gt;!&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This ensures the children of a component are correctly typed. Note how props are using the angled bracket syntax we used for events earlier. You will get an error if you use two sets of &lt;code&gt;:&lt;/code&gt;.  It is fair to say, however, that this pattern is &lt;a href="https://fettblog.eu/typescript-react-why-i-dont-use-react-fc/"&gt;debated&lt;/a&gt; but this is how I tend to operate.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrap Up
&lt;/h2&gt;

&lt;p&gt;This post was supposed to be a quick look at how to get started with Typescript with React and what you might commonly find in your initial steps with it. Hope it has helped. &lt;/p&gt;

&lt;p&gt;As for Typescript itself. Definitely consider picking it up if you are using React. Having a build process is something you are already familiar with and, while it is a little extra typing (no pun intended) It helps avoid issues later down the line when they are much harder to spot. The main takeaway here is that even a little typescript seasoning can be a tasty benefit to your apps even if you don't know all the ins and outs of it. And hopefully, it gives you a taste for learning more!&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>react</category>
    </item>
    <item>
      <title>Don't be afraid of ... Testing Fetch requests in React (Part 4 of 4)</title>
      <dc:creator>Lukie Kang</dc:creator>
      <pubDate>Sun, 31 Jan 2021 23:19:17 +0000</pubDate>
      <link>https://dev.to/neosaurrrus/don-t-be-afraid-of-testing-fetch-requests-in-react-part-4-of-4-80o</link>
      <guid>https://dev.to/neosaurrrus/don-t-be-afraid-of-testing-fetch-requests-in-react-part-4-of-4-80o</guid>
      <description>&lt;p&gt;So this is more for my own reference as part of a series on testing. Since I picked up testing React, what I have learnt has become stale so I'd really recommend a browse of &lt;a href="https://kentcdodds.com/blog/common-mistakes-with-react-testing-library"&gt;Kent C.Dodds's post&lt;/a&gt; to really boost your testing game in React and avoid some of the common issues people do in testing... which I do here!&lt;/p&gt;

&lt;p&gt;In previous posts, I have been going over how to test common things we would do in React such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Component Elements&lt;/li&gt;
&lt;li&gt;Forms&lt;/li&gt;
&lt;li&gt;Props&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is quite a few things in our testing toolbox. Now another common thing you might do in react is fetch data from a backend or external API. This can get a little hairy so I wanted to break it down and go slowly through it. In this post we will cover.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mocking APIs&lt;/li&gt;
&lt;li&gt;Asynchronous Testing&lt;/li&gt;
&lt;li&gt;Additional Information&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Mocking APIs
&lt;/h2&gt;

&lt;p&gt;Now let's assume we have a Book component which fetches data from an external API when it provides an ID. &lt;/p&gt;

&lt;p&gt;From previous posts, we know how to provide props and variables to a test, so we could easily give the test an ID to then fetch from the external API. This is doable but perhaps not a good idea. Still, we need to set up that initial step of the fetch request as that is a param we pass in when using the book component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;match&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;abc1234567&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We don't want to actually hit the API as that takes a little time to do and introduces a dependency to the API which makes it harder to reliably test.&lt;/p&gt;

&lt;p&gt;Instead,  we want to make up a result we can use for the test. To make generating fetch requests a snap I reach for a library called &lt;code&gt;jest-fetch-mock&lt;/code&gt; which can be installed by:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm install --save-dev jest-fetch-mock&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now, if this is something you are expecting to do a lot of, I recommend following the &lt;a href="https://www.npmjs.com/package/jest-fetch-mock"&gt;setup steps provided&lt;/a&gt;. For the sake of a punchy blog post we will do things quicker and dirtier.&lt;/p&gt;

&lt;p&gt;Once we have it installed we can override global fetch with our new package:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;global-fetch = require('jest-fetch-mock')&lt;/code&gt; allows us to override the normal fetch for our test suite and instead allow us to provide our own JSON.&lt;/p&gt;

&lt;p&gt;Now we have global fetch configured we need to perform the fetch in our test, here is an example, obviously, we need to tailor it according to the fetch we would want to perform. Its a really common error for me to fail to replicate what is coming back from the fetch so its worth triple-checking your mocked response is in the right format!:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mockResponseOnce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1984&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;author&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;George Orwell&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So let's see how our test now looks with all that information:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;cleanup&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-testing-library&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Book&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./Book&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nb"&gt;global&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fetch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;jest-fetch-mock&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Makes the test use 'jest-fetch-mock&lt;/span&gt;

&lt;span class="nx"&gt;afterEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;cleanup&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mockClear&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;match&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;//our params to grab the book info from the ID provided.&lt;/span&gt;
    &lt;span class="na"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;abc1234567&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;Book /&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mockResponseOnce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1984&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;author&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;George Orwell&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;}))&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Book&lt;/span&gt; &lt;span class="nx"&gt;match&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;match&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="sr"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;)
&lt;/span&gt;  &lt;span class="nx"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We are not actually testing anything yet but that will come... first we have a little problem.&lt;/p&gt;

&lt;p&gt;If you check the debug (making sure to use the fetched data in some way in the book component) you'll notice that the data we fetched isn't being used. This starts to make sense when you consider it is a fetch request and they are asynchronous. We need a way to wait for the result to come back before proceeding. Handily enough, my next section is called...&lt;/p&gt;

&lt;h2&gt;
  
  
  Asynchronous Tests
&lt;/h2&gt;

&lt;p&gt;How do we get this data to show?&lt;/p&gt;

&lt;p&gt;&lt;code&gt;waitForElement&lt;/code&gt; is some magic in React Testing Library that waits for the element to show up before proceeding. We grab it from React Testing Library like so:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;import {render, cleanup, waitForElement} from 'react-testing-library&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;As with previous tests we need to define a target using a query such as &lt;em&gt;getByText&lt;/em&gt;. But of course the problem is that we need to wait for that to exist on the page, to do that we need to make the test asynchronous. That is not as scary as it may sound as we can use the &lt;strong&gt;async and await&lt;/strong&gt; syntax, like so..&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Book&lt;/span&gt;&lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="c1"&gt;//other stuff&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;book&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;getByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1984&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;//This will NOT work as the element doesn't exist.&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;waitForElement&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;getByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1984&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;//This waits for the element to exist so that...&lt;/span&gt;
  &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;getByTestId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;book-title&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1984&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;//...this WILL work.&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And.... you should have the book data coming through in the debug view. A common issue is getting the mock fetch in the correct format your component is expecting. Let's have a look at the test in full:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;cleanup&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;waitForElement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getAllByTestId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-testing-library&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Book&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./Book&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nb"&gt;global&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fetch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;jest-fetch-mock&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;afterEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;cleanup&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mockClear&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;match&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;abc1234567&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;book&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  &lt;span class="c1"&gt;//makes life easier as we can reference this in multiple places in the test.&lt;/span&gt;
    &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1984&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;author&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;George Orwell&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;Book /&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mockResponseOnce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;book&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;getByTestId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Book&lt;/span&gt; &lt;span class="nx"&gt;match&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;match&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="sr"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;)
&lt;/span&gt;  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;waitForElement&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;getByTestId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;book-title&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

  &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;getByTestId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;book-title&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;book&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As for the JS, this is a snippet of how it might look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;Book&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;book&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;componentDidMount&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;//Example API call&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`https://somebookapi.com`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;book&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;re&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;hs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="nx"&gt;book&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;book&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;book&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;testid&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;loading&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Loading&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&amp;gt;; /&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;This&lt;/span&gt; &lt;span class="nx"&gt;check&lt;/span&gt; &lt;span class="nx"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;important&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;it&lt;/span&gt; &lt;span class="nx"&gt;stops&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;element&lt;/span&gt; &lt;span class="nx"&gt;existing&lt;/span&gt; &lt;span class="nx"&gt;before&lt;/span&gt; &lt;span class="nx"&gt;it&lt;/span&gt; &lt;span class="nx"&gt;has&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;API&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nx"&gt;You&lt;/span&gt; &lt;span class="nx"&gt;could&lt;/span&gt; &lt;span class="nx"&gt;add&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;test&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;check&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="nx"&gt;prior&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;waitForElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; 
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;testid&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;book-title&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;book&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&amp;gt; /&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;The&lt;/span&gt; &lt;span class="nx"&gt;element&lt;/span&gt; &lt;span class="nx"&gt;we&lt;/span&gt; &lt;span class="nx"&gt;are&lt;/span&gt; &lt;span class="nx"&gt;looking&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h3&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;book&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;author&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h3&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Phew, there is a number of steps to getting it up and running but as long as you take it step-by-step and know the right react testing library magic you should get through it.&lt;/p&gt;

&lt;p&gt;As always this was just a look at one way of getting async tests to work, depending on what exactly you are doing there may be a better approach. The Jest docs has &lt;a href="https://jestjs.io/docs/en/asynchronous"&gt;good info&lt;/a&gt; about several async methods. So I would give that a good read when you start thinking about it. &lt;/p&gt;

&lt;h2&gt;
  
  
  Neater Testing with the &lt;strong&gt;tests&lt;/strong&gt; folder
&lt;/h2&gt;

&lt;p&gt;There is plenty you can test, and I have only covered a few testing angles for the sake of simplicity. Before you know it you will have test files everywhere and I haven't really mentioned a convention of how to organise them.&lt;/p&gt;

&lt;p&gt;For react apps I try and group components that related to a particular model, say Books. We don't have to have our tests sitting in the same folder as the component, there is a special folder &lt;code&gt;__tests__&lt;/code&gt; where it is expected to place our tests. Remember that you need to update the component imports in the tests as well as any other components that rely on the moved files.&lt;/p&gt;

&lt;h2&gt;
  
  
  Code Coverage
&lt;/h2&gt;

&lt;p&gt;You may hear people that are really into testing say things like, "our app has 95% test coverage" which sounds pretty impressive but what do they mean? Let's see if we can work it out by checking our own coverage:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm test -- --coverage&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Wierd syntax but it will spit you out a table breaking down, on a component by component basis how much of your code is covered by a test, splitting it up by Statements, Branches, Functions and Lines.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;--------------------------|----------|----------|----------|----------|-------------------|
File                      |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
--------------------------|----------|----------|----------|----------|-------------------|
All files                 |    46.07 |    19.35 |    46.67 |    60.66 |                   |
 App.js                   |       50 |      100 |        0 |       50 |                13 |
 Book.js                  |      100 |      100 |      100 |      100 |                   |
 Book Form.js             |      100 |      100 |      100 |      100 |                   |
 BooksList.js             |    90.91 |      100 |      100 |       90 |                22 |
 NewBook.js               |      100 |      100 |      100 |      100 |                   |
 index.js                 |        0 |        0 |        0 |        0 |     1,2,3,4,5,7,8 |
 registerServiceWorker.js |        0 |        0 |        0 |        0 |... 25,126,127,128 |
--------------------------|----------|----------|----------|----------|-------------------|
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I wouldn't lose too much sleep over 'All Files' value as there is a bunch of files that you typically don't care for testing. &lt;/p&gt;

&lt;p&gt;Code Coverage can point out testing gaps in the code but it does not say if the tests are actually good ones. Use it as a pointer where improvements might be needed but not as a score for how good your testing is.&lt;/p&gt;

&lt;h2&gt;
  
  
  That's a wrap
&lt;/h2&gt;

&lt;p&gt;Ok, I have written a fair amount of words with regards to testing and I feel like I have only scratched the surface! Since writing this, this information is already getting superseded. But hopefully how I picked it up is a good starting point in general.  There is much more the tools used can do with regards to testing so all I can say is to have the &lt;a href="https://jestjs.io/docs/en/getting-started"&gt;Jest&lt;/a&gt; and &lt;a href="https://testing-library.com/docs/"&gt;React Testing Library&lt;/a&gt; docs handy when starting to build out your own tests and see what works best for you.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Don't Be Afraid of ... Snapshot Testing and Mocking Forms and Props in React</title>
      <dc:creator>Lukie Kang</dc:creator>
      <pubDate>Sun, 24 Jan 2021 23:20:22 +0000</pubDate>
      <link>https://dev.to/neosaurrrus/don-t-be-afraid-of-snapshot-testing-and-mocking-forms-and-props-in-react-4i3k</link>
      <guid>https://dev.to/neosaurrrus/don-t-be-afraid-of-snapshot-testing-and-mocking-forms-and-props-in-react-4i3k</guid>
      <description>&lt;p&gt;In our &lt;a href="https://dev.to/neosaurrrus/don-t-be-afraid-of-testing-react-with-react-testing-library-1k6j"&gt;last post&lt;/a&gt;, we got introduced to React Testing via React Testing Library. For the sake of keeping things short and sweet, we left out a few extra things to talk about. For that reason, this post will be quite a mixture of things. In this post we will look at:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Snapshot Testing&lt;/li&gt;
&lt;li&gt;Mocking a Form submission&lt;/li&gt;
&lt;li&gt;Testing for errors&lt;/li&gt;
&lt;li&gt;Testing Specific Input Values&lt;/li&gt;
&lt;li&gt;Negative Assertions&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Snapshot Testing.
&lt;/h2&gt;

&lt;p&gt;Snapshot testing sounds a bit like what it sounds like. If you took a photo of the resulting code, did something then happen that makes it look different to that photo? Because we take the snapshot at a high-level on the component, typically the enclosing Div Snapshot testing lets us watch for changes across everything under that element. However, since Snapshot testing compares to a moment frozen in time, it works great for components that are static in nature, but ones with dynamic changeable elements, they will just be noise. Certainly, they get in the way while actually doing TDD. Anyhow. let's look at implementing it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Implementing Snapshot Testing
&lt;/h3&gt;

&lt;p&gt;Jest makes this a doddle. First we need to grab &lt;code&gt;container&lt;/code&gt; from our render:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;const {container} = render(&amp;lt;NewBook/&amp;gt;)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Container being the contents of the rendered component &lt;strong&gt;including any child components&lt;/strong&gt;. Then we want to say what we expect to match the Snapshot:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;expect(container.firstChild).toMatchSnapshot();&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The firstChild in this regard is the enclosing div. &lt;/p&gt;

&lt;p&gt;Soon as you have done that for the first time, Jest will do something cool, it will create the snapshot for us in the &lt;code&gt;__snapshots__&lt;/code&gt; folder. If you check it out you will see it is basically the output of the enclosing div. That's cool but here what I said about it being best for things that done change very often, what if you decide you wanted to add or tweak something? For example, an extra &lt;/p&gt;
&lt;p&gt; tag? Soon as you have done that the test suite will be pointing out it no longer matches the snapshot:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;expect(value).toMatchSnapshot() Received value does not match stored snapshot 1. - Snapshot&lt;/p&gt;

&lt;p&gt;Snapshot Summary&lt;br&gt;
1 snapshot test failed in 1 test suite. Inspect your code changes or press &lt;code&gt;u&lt;/code&gt; to update them.`&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If it was a tweak that was intended, then as it says, it's straightforward to update the snapshot with a tap of the &lt;code&gt;u&lt;/code&gt; key. This also makes it easy to accept something that has not been intended so be careful that Snapshot does not make things too easy for you to the point you snapshot intended stuff.&lt;/p&gt;

&lt;p&gt;Still, snapshot testing is a very useful way of quickly flagging when something changes and definitely should be considered for less dynamic components. This not intended as a replacement for unit testing, and it's not really practical to write a snapshot so they are not really compatible with TDD principles but provide a good quick additional layer of testing. You can learn more from the &lt;a href="https://jestjs.io/docs/en/snapshot-testing"&gt;JEST Documentation about Snapshots&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Mocking and Spying a Form Submission
&lt;/h2&gt;

&lt;p&gt;Ok, so let's take another look at Mocking which I touched on in my first testing post. But this time we can apply it to a more complex real-world example. Namely, let's look at a testing a form component. This is a common use case for mocking a function as we don't want to actually submit data to the database when we test things. I am sure we all have databases that are full of entries like "test" and "aaaa" from our manual testing days, let's see about reducing that a little!&lt;/p&gt;

&lt;p&gt;So let's go with a New Book Form that takes a book title and submits it, not too complex but will do as an example. First of all let's build out the test to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Check the button exists, &lt;/li&gt;
&lt;li&gt;And tell the test suite to click it.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;`&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;cleanup&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fireEvent&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-testing-library&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;//Added FireEvent from React Testing Library&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;BookForm&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./BookForm&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;afterEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cleanup&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;BookForm&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getByText&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;BookForm&lt;/span&gt;&lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;getByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Submit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;tagName&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;BUTTON&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;//Looks for an element with the text Submit, just for the sake of being different.&lt;/span&gt;
  &lt;span class="nx"&gt;fireEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;getByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Submit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="nx"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So let's build the component with the button and also a little cheeky function when the form is submitted:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;BookForm&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
               &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;form&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;testid&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;book-form&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="nx"&gt;onSubmit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;clicked the button!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
                   &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;submit&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Submit&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;               &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/form&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="s2"&gt;```



The reason I added that click function is to show that when we run the test, we can see that `&lt;/span&gt;&lt;span class="nx"&gt;clicked&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="s2"&gt;` appears in the log:



&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;PASS  src/BookForm.test.js&lt;br&gt;
  ● Console&lt;br&gt;
    console.log src/BookForm.js:10&lt;br&gt;
      clicked the button!&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


That might be useful in testing things work in a quick and dirty way. But if that form submission actually did something, then our tests would start getting dangerous so we need a safe way to submit the form when testing. To do this we need to consider the pattern we use for the component so we can safely mock it. This involves providing the function that runs on submit via props. The component we will end up with looks like this:



````js
export default class BookForm extends Component {

    state = {
        text: ''
    }
    render() {
        const {submitForm} = this.props
        const {text} = this.state
        return (
            &amp;lt;div&amp;gt;
               &amp;lt;form data-testid='book-form' onSubmit={ ()=&amp;gt; submitForm({text})}&amp;gt;

                   &amp;lt;button type="submit"&amp;gt;Submit&amp;lt;/button&amp;gt;
               &amp;lt;/form&amp;gt;
            &amp;lt;/div&amp;gt;
        )
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Ok, so the big question here is, &lt;em&gt;why have we bumped the submitForm function to props?&lt;/em&gt; Because we need to change what that function does if it is run by our test compared to its normal job in the application. This will make sense when we look at the test we have written:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;cleanup&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fireEvent&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-testing-library&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;BookForm&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./BookForm&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;afterEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cleanup&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;onSubmit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;//Our new Spy function&lt;/span&gt;

&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;BookForm&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getByText&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;queryByTestId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;BookForm&lt;/span&gt; &lt;span class="nx"&gt;submitForm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;onSubmit&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="sr"&gt; /&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;The&lt;/span&gt; &lt;span class="nx"&gt;spy&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;used&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;submit&lt;/span&gt; &lt;span class="nx"&gt;form&lt;/span&gt;

  &lt;span class="c1"&gt;//Unit Tests to check elements exist&lt;/span&gt;
  &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;queryByTestId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;book-form&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nx"&gt;toBeTruthy&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;queryByTestId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;book-form&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;tagName&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;FORM&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;getByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Submit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;tagName&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;BUTTON&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="c1"&gt;//Check Form Submits&lt;/span&gt;
  &lt;span class="nx"&gt;fireEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;getByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Submit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;onSubmit&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toHaveBeenCalledTimes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;//This tests makes sure we van submit the spy function&lt;/span&gt;
  &lt;span class="nx"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="s2"&gt;```



So to repeat what the comments say, we...:

1. Create a spy function that does nothing
2. This function is passed via props when we render the component.
3. We test to see if it runs with a `&lt;/span&gt;&lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;onSubmit&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toHaveBeenCalledTimes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;`. Which hopefully it does.

This is all very clever but we have not done much but tested the form submits ok. Which is important but let's take things a step further looking at the inputs that are submitted.


### Bonus: Spying on Console Errors

We can spy on pretty much anything we like. Even errors when a component is not called properly. Let's say, for example, we had a component that needs a bunch of props with specific proptypes defined, we may want to test what happens when we don't provide them. So we can use the mocking function to handle the console errors like so:



````js
console.error = jest.fn()
test('&amp;lt;ExampleComponent'&amp;gt;, () =&amp;gt; {
  render(&amp;lt;ExampleComponent /&amp;gt;)
    expect(console.error).toBeCalled()
});
```&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="nx"&gt;endraw&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="nx"&gt;Of&lt;/span&gt; &lt;span class="nx"&gt;course&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="nx"&gt;gets&lt;/span&gt; &lt;span class="nx"&gt;rid&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="nx"&gt;will&lt;/span&gt; &lt;span class="nx"&gt;still&lt;/span&gt; &lt;span class="nx"&gt;show&lt;/span&gt; &lt;span class="nx"&gt;any&lt;/span&gt; &lt;span class="nx"&gt;errors&lt;/span&gt; &lt;span class="nx"&gt;that&lt;/span&gt; &lt;span class="nx"&gt;may&lt;/span&gt; &lt;span class="nx"&gt;occur&lt;/span&gt; &lt;span class="nx"&gt;due&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;lack&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt; &lt;span class="nx"&gt;passed&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;

&lt;span class="nx"&gt;Right&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;back&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;our&lt;/span&gt; &lt;span class="nx"&gt;scheduled&lt;/span&gt; &lt;span class="nx"&gt;blogging&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;

&lt;span class="err"&gt;##&lt;/span&gt; &lt;span class="nx"&gt;Specifying&lt;/span&gt; &lt;span class="nx"&gt;Input&lt;/span&gt; &lt;span class="nx"&gt;Values&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nx"&gt;testing&lt;/span&gt;

&lt;span class="nx"&gt;To&lt;/span&gt; &lt;span class="nx"&gt;make&lt;/span&gt; &lt;span class="nx"&gt;our&lt;/span&gt; &lt;span class="nx"&gt;testing&lt;/span&gt; &lt;span class="nx"&gt;more&lt;/span&gt; &lt;span class="nx"&gt;aligned&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;real&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;life&lt;/span&gt; &lt;span class="nx"&gt;we&lt;/span&gt; &lt;span class="nx"&gt;may&lt;/span&gt; &lt;span class="nx"&gt;want&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;write&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;test&lt;/span&gt; &lt;span class="nx"&gt;that&lt;/span&gt; &lt;span class="nx"&gt;checks&lt;/span&gt; &lt;span class="nx"&gt;that&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;form&lt;/span&gt; &lt;span class="nx"&gt;can&lt;/span&gt; &lt;span class="nx"&gt;be&lt;/span&gt; &lt;span class="nx"&gt;submitted&lt;/span&gt; &lt;span class="kd"&gt;with&lt;/span&gt; &lt;span class="nx"&gt;certain&lt;/span&gt; &lt;span class="nx"&gt;specified&lt;/span&gt; &lt;span class="nx"&gt;inputs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nx"&gt;In&lt;/span&gt; &lt;span class="nx"&gt;our&lt;/span&gt; &lt;span class="nx"&gt;example&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;we&lt;/span&gt; &lt;span class="nx"&gt;want&lt;/span&gt; &lt;span class="nx"&gt;our&lt;/span&gt; &lt;span class="nx"&gt;Book&lt;/span&gt; &lt;span class="nx"&gt;Form&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;have&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nx"&gt;The&lt;/span&gt; &lt;span class="nx"&gt;way&lt;/span&gt; &lt;span class="nx"&gt;you&lt;/span&gt; &lt;span class="nx"&gt;might&lt;/span&gt; &lt;span class="nx"&gt;approach&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="nx"&gt;is&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;follows&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nx"&gt;Find&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;way&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;target&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;relevant&lt;/span&gt; &lt;span class="nx"&gt;part&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;be&lt;/span&gt; &lt;span class="nx"&gt;tested&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt; &lt;span class="nx"&gt;field&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nx"&gt;Change&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nx"&gt;Check&lt;/span&gt; &lt;span class="nx"&gt;that&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;form&lt;/span&gt; &lt;span class="nx"&gt;was&lt;/span&gt; &lt;span class="nx"&gt;submitted&lt;/span&gt; &lt;span class="kd"&gt;with&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="nx"&gt;we&lt;/span&gt; &lt;span class="nx"&gt;wanted&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;

&lt;span class="nx"&gt;That&lt;/span&gt; &lt;span class="nx"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;pretty&lt;/span&gt; &lt;span class="nx"&gt;good&lt;/span&gt; &lt;span class="nx"&gt;but&lt;/span&gt; &lt;span class="nx"&gt;there&lt;/span&gt; &lt;span class="nx"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;gotcha&lt;/span&gt; &lt;span class="nx"&gt;you&lt;/span&gt; &lt;span class="nx"&gt;need&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;be&lt;/span&gt; &lt;span class="nx"&gt;aware&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nx"&gt;Changing&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt; &lt;span class="nx"&gt;does&lt;/span&gt; &lt;span class="nx"&gt;not&lt;/span&gt; &lt;span class="nx"&gt;cause&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;s state to update in our test, we need to use a **change* event to update the value for the change to occur. Here are the additional parts we need to add to do this:
{% raw %}



````js
test(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;BookForm&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;, () =&amp;gt; {
  const {getByLabelText} = render(&amp;lt;BookForm submitForm={onSubmit} /&amp;gt;) //Adding the getByLabelText

  //1. Unit Test to check our input element exists
  expect(getByLabelText(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="nx"&gt;Title&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;).tagName).toBe(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="nx"&gt;INPUT&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;) //test to make sure the input is there

  //2. change the Input Value using the change event.
  fireEvent.change(getByLabelText(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="nx"&gt;Title&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;), {target: {value: "Girl, Woman, Other"}}) //This event sets the value of the input and lets the change affect the state. 

  //3. Check Form Submits as expected
  fireEvent.click(getByText(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="nx"&gt;Submit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;))
  expect(onSubmit).toHaveBeenCalledWith({title: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="nx"&gt;Girl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Woman&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Other&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;}) //This checks that the submission has the title we asked it to have earlier.

```



  Note that I am using a new query, *getByLabelText* which, unsurprisingly looks at the text of the label to find the element we are after. Step 2, is where we use our fireEvent. since our target is the input element, we need to drill down to find our value and change it. Finally, we can check what our Spy function used with the *toHaveNeenCalledWith* method which is hopefully an easy one to understand. 

So we better see what the React code looks like that passes these tests:



  ```js
import React, { Component } from &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="nx"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;
export default class BookForm extends Component {

    state = {
        title: &lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="s1"&gt; //what gets sent on submit
    }

    render() {
        const {submitForm} = this.props
        const {title} = this.state
        return (
            &amp;lt;div&amp;gt;
               &amp;lt;form data-testid=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="nx"&gt;book&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt; onSubmit={ ()=&amp;gt; submitForm({title})}&amp;gt;
                   &amp;lt;label htmlFor="title"&amp;gt;Title&amp;lt;/label&amp;gt; //Remember that it is the text of the element our test is looking for not the HTMLFor
                   &amp;lt;input id="title" type="text" onChange={(e) =&amp;gt; this.setState({title: e.target.value})}&amp;gt;&amp;lt;/input&amp;gt; //Quick and Dirty input controlling
                   &amp;lt;button type="submit"&amp;gt;Submit&amp;lt;/button&amp;gt;
               &amp;lt;/form&amp;gt;
            &amp;lt;/div&amp;gt;
        )
    }
}
```



Cool, now it isn&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;most&lt;/span&gt; &lt;span class="nx"&gt;complex&lt;/span&gt; &lt;span class="nx"&gt;form&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;world&lt;/span&gt; &lt;span class="nx"&gt;but&lt;/span&gt; &lt;span class="nx"&gt;hopefully&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;you&lt;/span&gt; &lt;span class="nx"&gt;can&lt;/span&gt; &lt;span class="nx"&gt;see&lt;/span&gt; &lt;span class="nx"&gt;how&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;techniques&lt;/span&gt; &lt;span class="nx"&gt;can&lt;/span&gt; &lt;span class="nx"&gt;be&lt;/span&gt; &lt;span class="nx"&gt;scaled&lt;/span&gt; &lt;span class="nx"&gt;up&lt;/span&gt; &lt;span class="nx"&gt;accordingly&lt;/span&gt; &lt;span class="nx"&gt;and&lt;/span&gt; &lt;span class="nx"&gt;also&lt;/span&gt; &lt;span class="nx"&gt;are&lt;/span&gt; &lt;span class="nx"&gt;getting&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;grasp&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;how&lt;/span&gt; &lt;span class="nx"&gt;simply&lt;/span&gt; &lt;span class="nx"&gt;we&lt;/span&gt; &lt;span class="nx"&gt;test&lt;/span&gt; &lt;span class="nx"&gt;dynamic&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nx"&gt;If&lt;/span&gt; &lt;span class="nx"&gt;you&lt;/span&gt; &lt;span class="kd"&gt;set&lt;/span&gt; &lt;span class="nx"&gt;up&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;snapshot&lt;/span&gt; &lt;span class="nx"&gt;test&lt;/span&gt; &lt;span class="nx"&gt;earlier&lt;/span&gt; &lt;span class="nx"&gt;you&lt;/span&gt; &lt;span class="nx"&gt;will&lt;/span&gt; &lt;span class="nx"&gt;now&lt;/span&gt; &lt;span class="nx"&gt;see&lt;/span&gt; &lt;span class="nx"&gt;they&lt;/span&gt; &lt;span class="nx"&gt;can&lt;/span&gt; &lt;span class="nx"&gt;be&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;little&lt;/span&gt; &lt;span class="nx"&gt;annoying&lt;/span&gt; &lt;span class="nx"&gt;when&lt;/span&gt; &lt;span class="nx"&gt;you&lt;/span&gt; &lt;span class="nx"&gt;are&lt;/span&gt; &lt;span class="nx"&gt;writing&lt;/span&gt; &lt;span class="nx"&gt;out&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;

&lt;span class="err"&gt;###&lt;/span&gt; &lt;span class="nx"&gt;Bonus&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Negative&lt;/span&gt; &lt;span class="nx"&gt;Assertions&lt;/span&gt;

&lt;span class="nx"&gt;In&lt;/span&gt; &lt;span class="nx"&gt;our&lt;/span&gt; &lt;span class="nx"&gt;test&lt;/span&gt; &lt;span class="nx"&gt;we&lt;/span&gt; &lt;span class="nx"&gt;had&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;following&lt;/span&gt; &lt;span class="nx"&gt;line&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; 

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;onSubmit&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toHaveBeenCalledWith&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Girl, Woman, Other&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;  

&lt;span class="nx"&gt;Which&lt;/span&gt; &lt;span class="nx"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;checking&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nx"&gt;that&lt;/span&gt; &lt;span class="nx"&gt;assertion&lt;/span&gt; &lt;span class="nx"&gt;is&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nx"&gt;it&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="nx"&gt;did&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="nx"&gt;happen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nx"&gt;There&lt;/span&gt; &lt;span class="nx"&gt;might&lt;/span&gt; &lt;span class="nx"&gt;be&lt;/span&gt; &lt;span class="nx"&gt;occasions&lt;/span&gt; &lt;span class="nx"&gt;where&lt;/span&gt; &lt;span class="nx"&gt;passing&lt;/span&gt; &lt;span class="nx"&gt;means&lt;/span&gt; &lt;span class="nx"&gt;checking&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nx"&gt;something&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="nx"&gt;did&lt;/span&gt; &lt;span class="nx"&gt;not&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="nx"&gt;happen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nx"&gt;In&lt;/span&gt; &lt;span class="nx"&gt;Jest&lt;/span&gt; &lt;span class="nx"&gt;that&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;s as easy as adding a `not` as part of the method like so:

&amp;gt; expect(onSubmit).not.toHaveBeenCalledWith({title: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="nx"&gt;Girl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Woman&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Other&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;}) 

This can be useful when, for example, you are testing what happens when data is not provided by props to a component that needs them. Which is handy as our next topic is...


## Mocking Props

So we are able to emulate form data, but another thing we commonly deal with in React is props. If our component needs props, we need a way of providing some. On a basic level, this is quite straightforward if all the above-made sense. In our test we need to: 

1. Mock out what the props should be 
2. Include those props when we render:



````js
console.error = jest.fn()

const book = {
  title: "The Stand"
}

test(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Book&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;without&lt;/span&gt; &lt;span class="nx"&gt;Book&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;, () =&amp;gt; { //No props so 
  render(&amp;lt;Book /&amp;gt;)
  expect(console.error).toHaveBeenCalled();
})

test(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Book&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kd"&gt;with&lt;/span&gt; &lt;span class="nx"&gt;Book&lt;/span&gt; &lt;span class="nx"&gt;Props&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;, () =&amp;gt; {
  render(&amp;lt;Book book={book}/&amp;gt;)
  expect(console.error).not.toHaveBeenCalled();
})
```



Pretty cool right? Well yes but now we are into multiple tests, we have a little gotcha to be aware of. In the example above we have two places where we check if the console.error has been called. Once without props and a second time without props where we expect that it will not run. However, if you run this it will fail as it will say that console.error was run the second time.... what gives?!

Put simply, console.error was called when it ran the first test so it thinks it was called when doing the second. The fix for this is fairly simple and requires a tweak to our clean up function.



````js
afterEach( () =&amp;gt; {
  cleanup
  console.error.mockClear()
})
```



Now the memory of the console error is cleared between tests and things are more normal.

There are unfortunately lots of little gotchas you will hit as you start testing real-world components. A common one is around React Router expecting things that are not found in the test by default, it&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt; &lt;span class="nx"&gt;beyond&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;scope&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="nx"&gt;blog&lt;/span&gt; &lt;span class="nx"&gt;post&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;cover&lt;/span&gt; &lt;span class="nx"&gt;all&lt;/span&gt; &lt;span class="nx"&gt;use&lt;/span&gt; &lt;span class="nx"&gt;cases&lt;/span&gt; &lt;span class="nx"&gt;but&lt;/span&gt; &lt;span class="nx"&gt;its&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;kind&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;thing&lt;/span&gt; &lt;span class="nx"&gt;that&lt;/span&gt; &lt;span class="nx"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;going&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;need&lt;/span&gt; &lt;span class="nx"&gt;some&lt;/span&gt; &lt;span class="nx"&gt;research&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="nx"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="c1"&gt;//stackoverflow.com/questions/43771517/using-jest-to-test-a-link-from-react-router-v4) when you encounter them. &lt;/span&gt;

&lt;span class="nx"&gt;Taking&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;step&lt;/span&gt; &lt;span class="nx"&gt;by&lt;/span&gt; &lt;span class="nx"&gt;step&lt;/span&gt; &lt;span class="nx"&gt;approach&lt;/span&gt; &lt;span class="nx"&gt;when&lt;/span&gt; &lt;span class="nx"&gt;writing&lt;/span&gt; &lt;span class="nx"&gt;tests&lt;/span&gt; &lt;span class="nx"&gt;and&lt;/span&gt; &lt;span class="nx"&gt;code&lt;/span&gt; &lt;span class="nx"&gt;does&lt;/span&gt; &lt;span class="nx"&gt;help&lt;/span&gt; &lt;span class="nx"&gt;narrow&lt;/span&gt; &lt;span class="nx"&gt;down&lt;/span&gt; &lt;span class="nx"&gt;and&lt;/span&gt; &lt;span class="nx"&gt;help&lt;/span&gt; &lt;span class="nx"&gt;search&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nx"&gt;solutions&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;such&lt;/span&gt; &lt;span class="nx"&gt;issues&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;

&lt;span class="err"&gt;##&lt;/span&gt; &lt;span class="nx"&gt;Wrapping&lt;/span&gt; &lt;span class="nx"&gt;things&lt;/span&gt; &lt;span class="nx"&gt;up&lt;/span&gt;

&lt;span class="nx"&gt;This&lt;/span&gt; &lt;span class="nx"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;one&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;those&lt;/span&gt; &lt;span class="nx"&gt;annoying&lt;/span&gt; &lt;span class="nx"&gt;blog&lt;/span&gt; &lt;span class="nx"&gt;posts&lt;/span&gt; &lt;span class="nx"&gt;where&lt;/span&gt; &lt;span class="nx"&gt;I&lt;/span&gt; &lt;span class="nx"&gt;touch&lt;/span&gt; &lt;span class="nx"&gt;on&lt;/span&gt; &lt;span class="nx"&gt;some&lt;/span&gt; &lt;span class="nx"&gt;things&lt;/span&gt; &lt;span class="nx"&gt;and&lt;/span&gt; &lt;span class="nx"&gt;ignore&lt;/span&gt; &lt;span class="nx"&gt;others&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nx"&gt;hopefully&lt;/span&gt; &lt;span class="nx"&gt;testing&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;forms&lt;/span&gt; &lt;span class="nx"&gt;and&lt;/span&gt; &lt;span class="nx"&gt;inputs&lt;/span&gt; &lt;span class="nx"&gt;are&lt;/span&gt; &lt;span class="nx"&gt;useful&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;most&lt;/span&gt; &lt;span class="nx"&gt;users&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nx"&gt;My&lt;/span&gt; &lt;span class="nx"&gt;goal&lt;/span&gt; &lt;span class="nx"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;give&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;grounding&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;what&lt;/span&gt; &lt;span class="nx"&gt;you&lt;/span&gt; &lt;span class="nx"&gt;would&lt;/span&gt; &lt;span class="nx"&gt;typically&lt;/span&gt; &lt;span class="nx"&gt;test&lt;/span&gt; &lt;span class="nx"&gt;and&lt;/span&gt; &lt;span class="nx"&gt;give&lt;/span&gt; &lt;span class="nx"&gt;you&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;little&lt;/span&gt; &lt;span class="nx"&gt;context&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;search&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;other&lt;/span&gt; &lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;

&lt;span class="nx"&gt;Next&lt;/span&gt; &lt;span class="nx"&gt;time&lt;/span&gt; &lt;span class="nx"&gt;we&lt;/span&gt; &lt;span class="nx"&gt;can&lt;/span&gt; &lt;span class="nx"&gt;look&lt;/span&gt; &lt;span class="nx"&gt;at&lt;/span&gt; &lt;span class="nx"&gt;testing&lt;/span&gt; &lt;span class="nx"&gt;APIs&lt;/span&gt; &lt;span class="nx"&gt;and&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;fun&lt;/span&gt; &lt;span class="nx"&gt;that&lt;/span&gt; &lt;span class="nx"&gt;brings&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>jest</category>
      <category>react</category>
    </item>
    <item>
      <title>Don't be Afraid of... Testing React with React Testing Library</title>
      <dc:creator>Lukie Kang</dc:creator>
      <pubDate>Mon, 18 Jan 2021 00:01:46 +0000</pubDate>
      <link>https://dev.to/neosaurrrus/don-t-be-afraid-of-testing-react-with-react-testing-library-1k6j</link>
      <guid>https://dev.to/neosaurrrus/don-t-be-afraid-of-testing-react-with-react-testing-library-1k6j</guid>
      <description>&lt;p&gt;Last time I explained a little about &lt;a href="https://dev.to/neosaurrrus/a-quick-intro-to-test-driven-development-oml"&gt;testing concepts and basic testing&lt;/a&gt;. As a React developer primarily, I tend to test things that are in React. So let's take a React-specific focus on testing, using tools that are the simplest ones to reach for. If you use React but have never bothered with testing, this might be useful to get started with minimal fuss.&lt;/p&gt;

&lt;p&gt;In this post we will look at:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;React Testing Library&lt;/li&gt;
&lt;li&gt;Unit Tests with Data Test Ids&lt;/li&gt;
&lt;li&gt;Interactive Tests with FireEvent&lt;/li&gt;
&lt;li&gt;Clean up&lt;/li&gt;
&lt;li&gt;Integration Testing with a little gotcha.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Introduction to React Testing Library
&lt;/h2&gt;

&lt;p&gt;To be able to test React code life is much easier with React Testing Library to allow us to properly query whats going on with React to build our tests.  The other popular dog in this world is Enzyme. Which is better is a debate for an internet search. But React Testing Library has more of a focus on the DOM and what the user actually sees whereas Enzyme focuses on the component itself. Remember that for later...&lt;/p&gt;

&lt;p&gt;If you are using create-react-app then the good news is that React Testing Library is built-in, otherwise, we can add it with:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm install --save-dev @testing-library/react&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Quick note: For the sake of clarity and brevity, I'll be breezing over the step by step TDD approach, namely:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;RED: Start with the simplest test that proves something is missing.&lt;/li&gt;
&lt;li&gt;GREEN: Write the simplest way to make the test pass.&lt;/li&gt;
&lt;li&gt;Refactor, improve the code till you are happy with it&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;But hopefully, you can see where those steps would exist in the process.&lt;/p&gt;

&lt;h2&gt;
  
  
  Unit Tests with Data Test IDs
&lt;/h2&gt;

&lt;p&gt;Let's pretend we want to have a component called Greeter whose job it is to show a div that says 'Howdy'. In the test file, we can provide assertions using a bunch of queries made available to us via React Testing Library (and DOM testing Library which is merged into it).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;render&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-testing-library&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Greeter&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./Greeter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;Greeter/&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getByTestId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;Greeter&lt;/span&gt;&lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;//outputs the dom to see what it is, useful for building tests so handy for building the test.&lt;/span&gt;
  &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;getByTestId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;greeter-heading&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;tagName&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;div&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;getByTestId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;example-heading&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Howdy&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So what's this getByTestId business? Data Test IDs let us identify elements so we can see what's going on there. We can assign a test id by simply adding the id in our JSX we write to pass the test:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;Greeter&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;greeting&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Howdy&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="c1"&gt;//Let's assume it is in the state because it might change&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;greeting&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;testid&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;greeter-heading&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 
                &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;greeting&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Of course, we don't have to use data test ids. To get a fuller taste of what you can query look at the cheatsheets for &lt;a href="https://testing-library.com/docs/react-testing-library/cheatsheet"&gt;React Testing Library&lt;/a&gt; and &lt;a href="https://testing-library.com/docs/dom-testing-library/cheatsheet"&gt;DOM Testing Library&lt;/a&gt;. It should cover everything you might want to query so I don't have to!&lt;/p&gt;

&lt;h2&gt;
  
  
  Building More Interactive Tests
&lt;/h2&gt;

&lt;p&gt;React is all about interactions so we need to test that the interface actually works by testing the interactivity of React.&lt;/p&gt;

&lt;p&gt;For this let's dream up a component that is a counter that ticks up every time we click the button. Let's jump to the point where we have a test and js file that is not yet interactive, in other words, a dumb button that says 0:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//Test File&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-testing-library&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Counter&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./Counter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;Counter /&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getByTestId&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Counter&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;counterButton&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;getByTestId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;counter-button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;counterButton&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tagName&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;BUTTON&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;counterButton&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;0&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;//JS&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;Counter&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;button&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;testid&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;counter-button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ok, so we need a test to define what happens when there is an event on that button. So first we need a way of watching events that are fired...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//Test File&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fireEvent&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-testing-library&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;//Added FireEvent from React Testing Library&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Counter&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./Counter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;Counter /&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getByTestId&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Counter&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;counterButton&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;getByTestId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;counter-button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;counterButton&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tagName&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;BUTTON&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;counterButton&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;0&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;fireEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;counterButton&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;//sends a click to the counter button&lt;/span&gt;
  &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;counterButton&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;//expect it to be one after the first click.&lt;/span&gt;
  &lt;span class="nx"&gt;fireEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;counterButton&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;//sends another click to the counter button&lt;/span&gt;
  &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;counterButton&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;//expect it to be two after the second click&lt;/span&gt;
  &lt;span class="nx"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;//This will output the DOM in the terminal after the additional clicks so its a good place to check whats happening.&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this point, our test suite should be telling us we are failing the test. Well, that's what happens if you have a button that does nothing so let's fix that...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;Counter&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;prevState&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="na"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;prevState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
        &lt;span class="p"&gt;}))&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;button&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; 
            &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;testid&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;counter-button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Cleanup, because testing isn't just always fun.
&lt;/h3&gt;

&lt;p&gt;One little housekeeping touch. We want to ensure that after each test we clean things back up so it's all fresh for the next step. Handily React Testing Library gives us a cleanup method just for that purpose if we add that, that will make sure each test has a clean slate.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fireEvent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;cleanup&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-testing-library&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;//Added from React Testing Library&lt;/span&gt;
&lt;span class="nx"&gt;afterEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cleanup&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;Counter /&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;//etc&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Without that, you will get duplicate values in the DOM which is not ideal. It's easy to forget about but please don't!&lt;/p&gt;

&lt;h2&gt;
  
  
  Integration Testing with Forms
&lt;/h2&gt;

&lt;p&gt;Ok so we have the basics down let's try and apply what we have learnt to a slightly more challenging but realistic example (but not that realistic, as you'll see)&lt;/p&gt;

&lt;p&gt;Let's imagine we have a React app that is all about books and one of the features we want is the ability to add a new book. For that we might want a component for a new book with a book form component that is used inside :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;NewBook&lt;/li&gt;
&lt;li&gt;BookForm&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I like to scaffold empty components before we get into the tests, but of course, that's up to you.&lt;/p&gt;

&lt;p&gt;So I would like the NewBook component to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Show a heading that says "Enter a New Book"&lt;/li&gt;
&lt;li&gt;Show the Book Form&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If we hold onto our test-id pattern from before it will be straightforward right? Here is our test...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;cleanup&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-testing-library&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;NewBook&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./NewBook&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;afterEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cleanup&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;NewBook&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getByTestId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;NewBook&lt;/span&gt;&lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;//Grab the tools we need for this next.&lt;/span&gt;

&lt;span class="c1"&gt;//Check Page Title is present and correct&lt;/span&gt;
 &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;heading&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;getByTestId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;page-title&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;//This id might be a good pattern between multiple components&lt;/span&gt;
 &lt;span class="nx"&gt;expert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;heading&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tagName&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;H1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;//Note the caps in 'h1'&lt;/span&gt;
 &lt;span class="nx"&gt;expert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;heading&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Enter a New Book&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;//Check Book Form is present&lt;/span&gt;
 &lt;span class="nx"&gt;expert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;queryByTestId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;book-form&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nx"&gt;toBeTruthy&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;//Lets talk about this line.&lt;/span&gt;
 &lt;span class="nx"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We use &lt;code&gt;queryByTestID&lt;/code&gt; where we are a bit less sure about if it exists or not. &lt;/p&gt;

&lt;p&gt;And... after checking that the test fails correctly, let's look at a first attempt New Book component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;BookForm&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./BookForm&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;NewBook&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
                 &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;testid&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;page-title&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Enter&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;New&lt;/span&gt; &lt;span class="nx"&gt;Book&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;                 &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;BookForm&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;testid&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;book-form&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And we get a Failure message like this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;expect(received).toBeTruthy() Expected value to be truthy, instead received null&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;What gives?!&lt;/p&gt;

&lt;p&gt;Remember at the start of the post, I said now React Testing Library looks at the resultant DOM whereas Enzyme looks at the Component. This is what makes it different. &lt;/p&gt;

&lt;p&gt;In this case, the Component &lt;strong&gt;BookForm&lt;/strong&gt; doesn't exist in the DOM, just its contents. So we need the data-testid to be on the form within the BookForm component. It is possible to mock the BookForm component (that's for another post) so that it can be picked up in the test, but the default 'thinking' of React Testing Library wants us to consider the result in the DOM. In other forms, it is integrated with the Book Form component.&lt;/p&gt;

&lt;p&gt;Soon as we create the BookForm component with something that has the testId we can pass the test (though maybe not very robustly):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;BookForm&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
               &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;form&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;testid&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;book-form&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/form&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The resultant HTML from the debug output might help show what is going on if you are a bit lost:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;    &lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;h1&lt;/span&gt;
              &lt;span class="na"&gt;data-testid=&lt;/span&gt;&lt;span class="s"&gt;"page-title"&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
              Enter a New Book
            &lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
              &lt;span class="nt"&gt;&amp;lt;form&lt;/span&gt;
                &lt;span class="na"&gt;data-testid=&lt;/span&gt;&lt;span class="s"&gt;"book-form"&lt;/span&gt;
              &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Phew, let's wrap this up
&lt;/h2&gt;

&lt;p&gt;We covered the basics of React Testing using React Testing Library. In order to do this, we are going lightly over a few concepts and breezing over the quality of the tests. Hopefully, that is something I'll find time to do a deeper dive of later, my main goal is to get people up and running with the infrastructure of React testing.&lt;/p&gt;

&lt;p&gt;However next time I think I will talk about the cool kid of Testing, Snapshot testing as that is cool... in the world of testing anyhow.&lt;/p&gt;

</description>
      <category>react</category>
      <category>testing</category>
    </item>
    <item>
      <title>Don't be afraid of ...Test-Driven Development</title>
      <dc:creator>Lukie Kang</dc:creator>
      <pubDate>Sun, 10 Jan 2021 23:52:35 +0000</pubDate>
      <link>https://dev.to/neosaurrrus/a-quick-intro-to-test-driven-development-oml</link>
      <guid>https://dev.to/neosaurrrus/a-quick-intro-to-test-driven-development-oml</guid>
      <description>&lt;p&gt;Test-Driven Development (TDD) is a term that gets a subset of people really excited and a larger chunk with dread. As I have been playing around with it more and more I wanted to reflect on my own understanding and the theory behind it as well as provide a small, non-scary example to help get things started. In this post we will cover:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;My own introduction&lt;/li&gt;
&lt;li&gt;What TDD is, and common concepts.&lt;/li&gt;
&lt;li&gt;A simple unit test using Jest&lt;/li&gt;
&lt;li&gt;A quick overview of Integration Testing and Mocks.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  My Introductions to TDD as a former business analyst.
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;"Well if I don't have the code, what am I supposed to test?" - Me, several years ago.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As a business analyst at the time, it turns out I actually was very test-orientated but just hadn't realised it: &lt;/p&gt;

&lt;p&gt;In a traditional project, the business analyst is the person who talks to the business and understands their needs and turns that into a set of requirements for the development team to implement. These requirements should be clear, measurable and actionable so that the development team builds what the business has asked for (which is debatable, to say the least).&lt;/p&gt;

&lt;p&gt;The point is that we are already thinking about the outcomes we'd like before we begin to make it happen. In coding, we get so wrapped up in the challenge of making it happen, TDD makes us consider what success actually looks like before we get started.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is TDD as others see it??
&lt;/h2&gt;

&lt;p&gt;Researching online it seems it is quite confusing, people have different views on how tests should be used with development.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Test Oriented Development, AKA lots of test are written for the code&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"Test-First Development", AKA We write the tests first, then write code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"Test-Driven Dev and Design", AKA the tests we write inform us of how we expect the code to function and be designed.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The point here is that the Internet holds many opinions on what TDD should be, so do different organisations. This is going to be my take on it because it's my blog. But as you learn more, try to keep an open mind and be flexible about how different people approach it. &lt;/p&gt;

&lt;p&gt;One term you might hear often is &lt;em&gt;production code&lt;/em&gt;. In the context of TDD, that is code that is not a test. Maybe it will be in the Production environment, maybe it won't but that's what we see it as.&lt;/p&gt;

&lt;p&gt;The origins of TDD comes from eXtreme Programming, a framework about how development should be. Slowly many elements of it have been getting adopted so it's no longer viewed as quite so extreme. From there the idea developed with Kent Beck writing his 2003 book "Understanding Test Driven Development". That's a good place to start if you want to get into the theory and have a reliable source of truth. But let's look at the common drawback of TDD you may hit early on...&lt;/p&gt;

&lt;h3&gt;
  
  
  It takes so long to write tests AND the code!
&lt;/h3&gt;

&lt;p&gt;Well yes, in a new team using TDD, it does take much longer to implement, but the bug fixing and testing steps are much more reduced. Overall it goes take longer but it comes with some benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Better design&lt;/li&gt;
&lt;li&gt;Fewer bugs in production&lt;/li&gt;
&lt;li&gt;Easier Integration Testing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In other words, TDD feels like a lot of faff because, yes it takes take much longer to produce the code when you have to write tests. As a new coder, writing code is what you focus on, so TDD feels like it just doubles your time.&lt;/p&gt;

&lt;p&gt;In the world of real shippable code we have to consider: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ensure it works as intended a whole&lt;/li&gt;
&lt;li&gt;Ensure it works with the rest of a bigger application or system (Integration Testing)&lt;/li&gt;
&lt;li&gt;Ensure old features didn't break when we added the new feature (Regression testing)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is a significant chunk of time overall, and this is where TDD really trims things down. Its annoyingly sensible, &lt;strong&gt;more work now to save work later&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;As we will see soon, it is also like having a team member who can point out when things go wrong so you don't have to. When it is done well, it makes a coder a happier coder, which is also a Good Thing. &lt;/p&gt;

&lt;h2&gt;
  
  
  Skills of TDD
&lt;/h2&gt;

&lt;p&gt;TDD isn't like, say using camelCase, where you either do or don't do. Its a discipline, like any physical exercise, that will feel uncomfortable and pointless, to begin with, but with practice and more complex scenarios, you will start developing the skills that make it worthwhile.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Writing Good tests, regardless of if you do it before or after.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If your test doesn't test your code in a meaningful way, if there are special cases we don't consider, for example, then the test won't do its job properly. Learning how to write a good test, or set of tests is an important skill. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Write the Test First&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Trying to think in terms of the test without code makes it easier. You get to think about requirements without getting hung up on in the implementation. However, this is a shift in mindset compared to building a function in a linear (e.g. Input, Do Something, Output) fashion.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Design Thinking with Tests&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is hard and something that comes with time but taking a step back to consider the requirements for the software itself in your testing is the key to writing the code you need to write and no more. &lt;/p&gt;

&lt;h2&gt;
  
  
  Red, Green, Refactor.
&lt;/h2&gt;

&lt;p&gt;If there is one thing to remember from this post, here it is.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;RED: Start with the simplest test that proves something is missing.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Think of a missing feature as a bug in your code. The test should fail because it doesn't exist yet. This is where design comes in, thinking smart about what you want to exist before you make it allows us to consider design rather than jump straight into the code. We want it to fail before we make it pass, this lets us prove the test is good, in other words, we test the test so we are confident in the test.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Green: Write the simplest way to make the test pass.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The next step is to pass the test. At this point, you can be confident that the code works &lt;em&gt;for that specific test&lt;/em&gt; because you have a test that works.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Refactor, improve the code till you are happy with it.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This might happen several times, repeating till the code is where you would like it, reducing duplicate code or tightening it up. This is important to ensure the code is something you enjoy working with over the long run. &lt;br&gt;
Additionally, when you have the tests in place you can quickly see if your refactoring is breaking things which makes it a more relaxing proposition.&lt;/p&gt;

&lt;p&gt;However, make sure the refactor is within the constraints of the test. the golden rule here is, &lt;strong&gt;we cannot write new functionality without writing a test&lt;/strong&gt;. It is so easy once our initial functionality works to instantly hop to the next bit of functionality but its an art to stop yourself and return to the test spec and plan the next move forward.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why 1 test first instead of writing 10?
&lt;/h2&gt;

&lt;p&gt;One by one forces us to work on one piece of functionality at a time, which leads to simpler maintainable code. When we have a dozen tests to pass, we often end up writing something that attempts to pass all of them efficient but opening up gaps of additional functionality. It's not something easily adopted I know but consider going test by test when starting, and see if, over time, that habit can form.&lt;/p&gt;
&lt;h1&gt;
  
  
  "Ok, cool I'm In but how do we do it?"
&lt;/h1&gt;

&lt;p&gt;To get started with it? Read on. &lt;/p&gt;

&lt;p&gt;To actually get good at it? Practice. Sorry, I wish there was an easier answer.&lt;/p&gt;

&lt;p&gt;The way I learnt was to look at a problem that is really straightforward so my brain doesn't need to worry about that side but instead focus on the test side of things. An example of which we are about to get into. Using something called Jest.&lt;/p&gt;
&lt;h2&gt;
  
  
  Jest, making life easy for testing in React but also Javascript.
&lt;/h2&gt;

&lt;p&gt;Jest is built into Create React App. Jest is a test runner that is easy and quick to run, as a React guy its what I turned to. It also can be installed via npm/yarn for JS. It's by no means the only test runner in town but its the one I will focus on.&lt;/p&gt;

&lt;p&gt;To learn more go to (&lt;a href="https://jestjs.io/"&gt;https://jestjs.io/&lt;/a&gt;). The docs are really easy to get going with some examples and some of the different things to do.&lt;/p&gt;

&lt;p&gt;We can launch Jest with &lt;code&gt;npm test&lt;/code&gt; automatically in a React app created with Create React App. Or in Node &lt;a href="https://jestjs.io/docs/en/getting-started.html"&gt;follow these steps&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;There are several ways to have test files that Jest can use. I typically create a &lt;code&gt;FILENAME.test.js&lt;/code&gt; in the same place as the code.&lt;/p&gt;
&lt;h2&gt;
  
  
  Our First Unit Test
&lt;/h2&gt;

&lt;p&gt;For the sake of quickness let's just create a function we are going to test in App.js of a new React App. We are going to try and build a function that adds two numbers.  Though we should write the test first as stated earlier, some prefer to  have the stub of the future code to exist before writing the test like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;add&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kc"&gt;null&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In your &lt;code&gt;App.test.js&lt;/code&gt; file, lets import the function and then write our first test:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./App&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;add&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So let us go through the key elements of this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We open a test function and we call it whatever name we like, something that explains what we are testing&lt;/li&gt;
&lt;li&gt;We declare a constant &lt;code&gt;value&lt;/code&gt; which has an example of how we'd use the function.&lt;/li&gt;
&lt;li&gt;We &lt;strong&gt;expect&lt;/strong&gt; value &lt;em&gt;to be&lt;/em&gt; 3&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The &lt;code&gt;expect&lt;/code&gt; line is the key one, there are a &lt;a href="https://jestjs.io/docs/en/expect"&gt;number of methods&lt;/a&gt; we can use to say what we expect to happen.&lt;/p&gt;

&lt;p&gt;Now we have written it, let's look at what the terminal where we ran &lt;code&gt;npm test&lt;/code&gt; is saying:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; FAIL  src/App.test.js
  ✕ add (3 ms)

  ● add

    expect(received).toBe(expected) // Object.is equality

    Expected: 3
    Received: null

       5 | test('add', () =&amp;gt; {
       6 |   const value = add(1,2);
    &amp;gt;  7 |   expect(value).toBe(3)
         |                 ^
       8 | })
       9 |
      10 |

      at Object.&amp;lt;anonymous&amp;gt; (src/App.test.js:7:17)

Test Suites: 1 failed, 1 total
Tests:       1 failed, 1 total
Snapshots:   0 total
Time:        3.241 s
Ran all test suites related to changed files.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ok, the test failed. This is &lt;strong&gt;good&lt;/strong&gt;, we have ticked off the first step of TDD: Write a test that fails!&lt;/p&gt;

&lt;p&gt;Next step, lets make it work however we can, hmm, this will do:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;add&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;total&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
  &lt;span class="nx"&gt;total&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;total&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;
  &lt;span class="nx"&gt;total&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;total&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;total&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And if we check our test terminal (as I like to call it):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; PASS  src/App.test.js
  ✓ add (2 ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        3.342 s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Woohoo, we have done it! Time to go party right? Ah no, making the test pass was just step 2. There is probably a refactor or two we can do to this code, so let us see what we can do.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;add&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Look how efficient that is now, we are such great coders! &lt;em&gt;But wait, what is happening in the test terminal?&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FAIL  src/App.test.js
  ✕ add (4 ms)

  ● add

    expect(received).toBe(expected) // Object.is equality

    Expected: 3
    Received: 2

       5 | test('add', () =&amp;gt; {
       6 |   const value = add(1,2);
    &amp;gt;  7 |   expect(value).toBe(3)
         |                 ^
       8 | })
       9 |
      10 |

      at Object.&amp;lt;anonymous&amp;gt; (src/App.test.js:7:17)

Test Suites: 1 failed, 1 total
Tests:       1 failed, 1 total
Snapshots:   0 total
Time:        0.962 s
Ran all test suites related to changed files.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ah nuts, it has failed! Just as well we had a test in place to tell us we made a mistake when refactoring! This is my favourite aspect, having something to watch our back while we get creative in making the code neater. Because it gives us information such as what is expected and what it got, it helps us narrow down the issue (which I am sure you can figure out yourself!). &lt;/p&gt;

&lt;p&gt;Since the above function would pass the test if we just returned 3 or even (-1, -3) we might want to consider adding another &lt;em&gt;assertion&lt;/em&gt;:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;expect(add(-1,-3)).toBe(-4)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now both assertions have to be true for the test to pass, adding additional assertions increases the bulletproof nature of the function.&lt;/p&gt;

&lt;p&gt;Now this example wasn't the most complex in the world but its a start. If we want to add extra functionality, TDD makes us write the test first to make sure we develop decent test coverage.&lt;/p&gt;

&lt;p&gt;Testing an individual function that stands alone is called &lt;strong&gt;a Unit Test&lt;/strong&gt; as opposed to testing, say a React Component that in turn renders or &lt;em&gt;integrates&lt;/em&gt; other components. That requires a different type of test...what would be a good name for them...&lt;/p&gt;

&lt;h2&gt;
  
  
  Integration Tests
&lt;/h2&gt;

&lt;p&gt;So some functions rely on other functions which impacts how we test, let's run through an example.&lt;/p&gt;

&lt;p&gt;Lets say we wanted to return a string that said how many people were at a school using the add function from before (arguably this would come in a refactor but lets be brief), we would write a test like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;schoolPopulation&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;schoolPopulation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nx"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;There are 110 people at the school&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As per step 1, we write something that fails the test:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;schoolPopulation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;teachers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;students&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;teachers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;students&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As the next step we write the thing that hopefully passes the test:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;schoolPopulation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;teachers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;students&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`There are &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;teachers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;students&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt; people at the school`&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Just because we can refactor now because mean we have to. It looks good to me. &lt;/p&gt;

&lt;p&gt;Now the thing to bear in mind here is that while the test is similar to the one we wrote for the Unit Test. It isn't a Unit Test because it depends on the add function working too. If we broke the add function this would break this test too even if, on its own, it works fine. What we need is a unit test for the &lt;code&gt;schoolPopulation&lt;/code&gt; function as this would help highlight which part of the chain is broken. This needs something we call Mocks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mocks, or Mock Functions.
&lt;/h2&gt;

&lt;p&gt;This will be a quick dip into the subject as I think it's creeping beyond the scope of my little introduction to TDD. &lt;br&gt;
In a nutshell, a mock is basically a fake function for our tests. While it can be useful to provide unit tests to a function that relies on other functions. It also is handy for testing functions that call an API or database, in other things you get want to actually run for the sake of testing.&lt;/p&gt;

&lt;p&gt;So if we look at our school population and add functions what Jest allows us to do is essentially intercept the function call to the add function and provide a fake result to use in the school population function.&lt;/p&gt;

&lt;p&gt;This is better shown first:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//In the schoolPopulation.test.js file&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;schoolPopulation&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./schoolPopulation&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./add&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./add&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="c1"&gt;//Instead of the add function we imported...&lt;/span&gt;
    &lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;//... use this fake function which returns 50 always.&lt;/span&gt;
&lt;span class="p"&gt;}))&lt;/span&gt;

&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;school population&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;schoolPopulation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nx"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;There are 50 people at the school&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;//&lt;/span&gt;
    &lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mockImplementation&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;//if we wanted, for some reason,  we can change what the fake add function gives us.&lt;/span&gt;

     &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;schoolPopulation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nx"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;There are 30 people at the school&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This starts getting more important as you dive deeper into the world of testing. But its important to understand that creating a mock dependence so the test can run without being affected by outside factors.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Phew, this was supposed to be a very quick primer on what TDD is and how to actually get started without getting bogged down in the details. There is a whole world under the little bit I have shown but hopefully, this is useful to understand how I leant and how you might be able to get your feet wet into quite a growing movement towards TDD.&lt;/p&gt;

</description>
      <category>tdd</category>
      <category>jest</category>
      <category>react</category>
    </item>
    <item>
      <title>10 things I Learned about Accessibility from UK News Sites</title>
      <dc:creator>Lukie Kang</dc:creator>
      <pubDate>Wed, 30 Dec 2020 21:41:58 +0000</pubDate>
      <link>https://dev.to/neosaurrrus/10-things-i-learned-about-accessibility-from-uk-news-sites-2ml0</link>
      <guid>https://dev.to/neosaurrrus/10-things-i-learned-about-accessibility-from-uk-news-sites-2ml0</guid>
      <description>&lt;p&gt;I recently performed a brief analysis of the accessibility of UK News sites, for two reasons:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Digital News Media is really important in allowing people to take part in society, democracy, and stay connected in an ever-complicating world. I was curious if there would a real impact on those who rely on accessibility features.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I also wanted to improve my knowledge to let accessible design become my natural thought process so I can make strides on that in 2021.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Combining my two interests, I decided to take a slice of UK News sites and see how they approach accessibility in order to grow my own thinking. The sites I chose are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;BBC News&lt;/li&gt;
&lt;li&gt;The Guardian&lt;/li&gt;
&lt;li&gt;The Daily Mail&lt;/li&gt;
&lt;li&gt;The Telegraph&lt;/li&gt;
&lt;li&gt;The Mirror&lt;/li&gt;
&lt;li&gt;The Times&lt;/li&gt;
&lt;li&gt;The Sun&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now a bunch of what I am going to say is very much opinionated and from the perspective of a regular Joe but hey, that's the point of a blog. For example, when I say something was not possible, that means that I couldn't figure it out. I might not be the sharpest of internet users out there but honestly, that's who is using your sites!&lt;/p&gt;

&lt;h2&gt;
  
  
  1. There is more done right than done wrong.
&lt;/h2&gt;

&lt;p&gt;It's easy to criticise, as I am about to do but it's important to say that overall they have done a good job, covering many of the basics to a point they don't get mentioned. But of course, that just means where they drop the ball becomes even more glaring. &lt;/p&gt;

&lt;p&gt;To all the developers and designers I'd say &lt;em&gt;Great work. learn from each other, if you took the best accessibility practices from each site you'd be perfect.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Cookie Prompt Pain
&lt;/h2&gt;

&lt;p&gt;You all know the fun of cookie prompts news sites or not. One of the first things a keyboard-only user might have to do is try and find a way to get rid of it. So let's make that as painless as possible.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Good&lt;/strong&gt;: Have your cookie prompt at the top of the screen and the first thing to focus on. (BBC). &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fneosaurrrus%2Fblog-entries%2Fmaster%2Fpics%2F61%2Fbbc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fneosaurrrus%2Fblog-entries%2Fmaster%2Fpics%2F61%2Fbbc.png" alt="BBC Cookie"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Hmmm...&lt;/strong&gt;: Sticking the cookie prompt on the bottom can be a bit more confusing for tab logic, especially when you tab past it into the main content that is obscured (Mirror)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Not Great&lt;/strong&gt;: Now allowing the cookie prompt to be focusable at all. And also have a video popup you can focus on while you are at it. (Mail Online)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3. Please take my accessibility user money!
&lt;/h2&gt;

&lt;p&gt;Some news sites need people to pay for their content and there is nothing wrong with that. Subscription prompts tend to one of the first things we see and would be a chance to show all users the site is usable for them. So I was a little surprised to find that subscription prompts are generally less friendly than the content behind them! This is money left on the table when the content itself is often fine. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;OK:&lt;/strong&gt; Redirect the user to a subscription page with big clear elements explaining the options (The Times... though the tab order here could be improved)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Not Great:&lt;/strong&gt; Ask for support with a popup in the footer, but don't allow it to be focusable (The Guardian)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Really Not Great:&lt;/strong&gt; Use a subscription popup over content which is not focusable or screen readable and obscures the cookie prompt which means you have no idea where focus has gone. (The Telegraph)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fneosaurrrus%2Fblog-entries%2Fmaster%2Fpics%2F61%2Ftelegraph.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fneosaurrrus%2Fblog-entries%2Fmaster%2Fpics%2F61%2Ftelegraph.png" alt="Telegraph subscription"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Tab Order Vs Cool Layouts
&lt;/h2&gt;

&lt;p&gt;It is important for news sites to have a visually compelling layout, much like their physical versions, I get that. However, while a mouse pointer can follow wherever a user wants, it can be disorienting when the tab order does not follow what makes sense. This is such an easy thing to test but did throw up some odd results.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Good:&lt;/strong&gt; Small elements, that follow a logical pattern. Allowing a keyboard user can follow without thinking too hard (The BBC)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Okish:&lt;/strong&gt; Occasional long elements, causing the tab focus to jump large distances and giving keyboard users the chance to play "hide and seek" with the focus highlight (The Guardian)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Not Great:&lt;/strong&gt; Letting your tab focus follow a course no regular pair of eyeballs would. Occasionally vanishing somewhere for a few tabs before returning  (The Times)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Also Not Great:&lt;/strong&gt; Have a sidebar you can see but cannot focus on till you have reached the bottom of a very long main column (The Mail)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  5. Alt tags for images, sometimes silence is golden
&lt;/h2&gt;

&lt;p&gt;It's great if there is a description to your images, certainly, it is something that accessibility tests flag up easily. However, that doesn't mean that any text is better than no text.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Good:&lt;/strong&gt; Provide a short helpful description of what is found in the picture (BBC News)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;OK, fair enough... :&lt;/strong&gt; Don't provide a description and just let the screen reader skip over it. (The Guardian)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Really Not Great:&lt;/strong&gt; Set the alt text to be a copy of the headline text it is next to, making screen readers effectively say the same thing twice. Annoying no matter how cute the story is. (The Sun, The Times, The Mail)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fneosaurrrus%2Fblog-entries%2Fmaster%2Fpics%2F61%2Fmail.png%3F" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fneosaurrrus%2Fblog-entries%2Fmaster%2Fpics%2F61%2Fmail.png%3F" alt="Mail Seal"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Highlighting Interactive Elements highlights plenty of differences.
&lt;/h2&gt;

&lt;p&gt;Without moving a mouse, can you see what bits of the page would do something if you clicked/tapped on it? What about if you moved the mouse over it? And what if you tabbed onto it? It is clear then?&lt;/p&gt;

&lt;p&gt;The answers to those questions were so variable across news sites and quite subjective. More research is required but I personally found that a combination of color and underlining provided the clearest experience. &lt;/p&gt;

&lt;p&gt;Mre tangible issues stem from elements that don't appear to be interactive that actually are either due to formatting matching non-interactive areas.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Good:&lt;/strong&gt; Use of both colour and underlining when an interactive element is focused (The BBC)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Hmmm...:&lt;/strong&gt; Make the background a similar colour to the tab focus effectively making the element not highlight when focused. (The Guardian)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fneosaurrrus%2Fblog-entries%2Fmaster%2Fpics%2F61%2Fguardian.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fneosaurrrus%2Fblog-entries%2Fmaster%2Fpics%2F61%2Fguardian.png" alt="Guardian cookies"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Really Not Great:&lt;/strong&gt; No colour or text formatting when focused or hovered over (The Mirror)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  7. Your 3rd party content does matter
&lt;/h2&gt;

&lt;p&gt;It is understandable that news sites use advertisements and sponsored content to keep the money coming in. However while the main site can be made accessible, 3rd party content also needs to be held to the same standard as it affects the user's experience just the same as the rest of the content. &lt;/p&gt;

&lt;p&gt;I am not sure why advertisements wouldn't want to do something snappy for folks using screen readers but it doesn't appear to be the case in the test.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Good:&lt;/strong&gt;  Allowing a screen reader to recognise an ad, state that is an ad and moves on. (The Mirror)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hmmm...:&lt;/strong&gt; Make the screen reader recognise ad content as simply web content making it confusing what it is exactly (The Sun)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Really Not Great:&lt;/strong&gt; Have sponsored content that makes no concessions to screen readers and makes them read out ID numbers and such. (The Times) &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  8. A site can be experienced in different ways, screen reading tends to be where most issues lay.
&lt;/h2&gt;

&lt;p&gt;Following on from #4. There are actually three journeys through a site. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Your eyes as you look at what's there. Studies have shown it is isn't just left-to-right up-to-down. It's interesting seeing how different sites use this to their advantage, but this can open up challenges for the other journeys.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tabbing through content. Typically this will go along the navigation before following the article sequentially. Generally, this is logical on sites, by which I mean it follows what we see fairly well.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Being guided through it by a screen reader. This is one that most often exhibited strange behavior and most, unlike the visual experience. I am sure part of this is my lack of familiarity with screen readers but I definitely recognised things that did not quite make sense. Going through a site with a screen reader does take a relatively long time, they don't have the same ability to skip over irrelevant content as eyeballs do, so it's important to be respectful of the user's time.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Good:&lt;/strong&gt; Providing 'Skip to content' or 'Jump to navigation' functionality to allow a little agency in the tab and screen reader journey. (The Telegraph, The Sun)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Hmmm...:&lt;/strong&gt; Providing multiple links in an element adding additional complexity to screen readers and tab focusing. (The Mail)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Really Not Great:&lt;/strong&gt; Having visibly collapsed menus but making screen readers read through each option anyhow. (The Times)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  9. Lighthouse shines a helpful light, but plenty of shadows remain.
&lt;/h2&gt;

&lt;p&gt;I think a lot of people's plan of action for accessibility is to use Chrome's Lighthouse to make the numbers go higher. When it's high, job's done right? Not really, most of the sites had scores in the 80s but still had issues. Conversely, the BBC News site, which was perhaps the best all-round actually had the worst lighthouse score of the sites I tested.&lt;/p&gt;

&lt;p&gt;As mentioned in #5, meeting the criteria isn't as important as that criteria providing a net positive for accessibility. I do wonder if doggedly chasing perfect Lighthouse score incentives a few bad practices along the way.&lt;/p&gt;

&lt;p&gt;It also does not appear to give much weight to the frequency of a particular issue. Having a lot of different issues happen on one or two elements, is arguably better than one consistent issue that occurs everywhere. &lt;/p&gt;

&lt;p&gt;It is a good guide but to build for accessibility will involve getting more familiar with the &lt;a href="https://www.w3.org/TR/WCAG21/" rel="noopener noreferrer"&gt;WCAG&lt;/a&gt; to really take the details to heart.&lt;/p&gt;

&lt;h2&gt;
  
  
  10. There is much more to look at!
&lt;/h2&gt;

&lt;p&gt;My analysis was only scratching the surface of what makes a web site accessible. For a first look, it has some value but there are more areas that I would have loved to go into. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Alignment to WCAG2.1 and the upcoming WCAG2.2 for a more comprehensive analysis&lt;/li&gt;
&lt;li&gt;Looking at the different pages found on each site.&lt;/li&gt;
&lt;li&gt;Mobile users and devices beyond the standard desktop.&lt;/li&gt;
&lt;li&gt;Behaviour across different browsers, I noticed some issues in this regard but want to do a proper job on this.&lt;/li&gt;
&lt;li&gt;Involving actual users of common accessibility features. (I am sure this would be a good Fiverr type service)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Wrap up, my full results, and my secret shame...
&lt;/h2&gt;

&lt;p&gt;I collated my findings at my site, &lt;a href="http://newsa11y.com" rel="noopener noreferrer"&gt;newsa11y.com&lt;/a&gt;. Which, embarrassingly, needs a lot more accessibility work itself. It was intended as a quick MVP template to get something going. I hope to do the exercise again next year to perform a proper, deeper, clearer, and yes, accessible, analysis of the state of UK News media when it comes to accessibility, feel free to get in touch if this is something you'd love to help out with.&lt;/p&gt;

</description>
      <category>media</category>
      <category>a11y</category>
    </item>
    <item>
      <title>Figuring Out Gatsby #5 - GraphQL - How Gatsby eats data</title>
      <dc:creator>Lukie Kang</dc:creator>
      <pubDate>Tue, 29 Dec 2020 10:15:46 +0000</pubDate>
      <link>https://dev.to/neosaurrrus/figuring-out-gatsby-5-graphql-how-gatsby-eats-data-7jb</link>
      <guid>https://dev.to/neosaurrrus/figuring-out-gatsby-5-graphql-how-gatsby-eats-data-7jb</guid>
      <description>&lt;p&gt;In my last post I actually didn't talk much about Gatsby and instead set up a Sanity backend for Gatsby to ingest somehow.&lt;/p&gt;

&lt;p&gt;The gist of the Sanity backend is that we have the following data for our restaurant app to use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;dishes, our meals&lt;/li&gt;
&lt;li&gt;intolerances, things like gluten that can be in dishes&lt;/li&gt;
&lt;li&gt;employees, who work at the restaurant&lt;/li&gt;
&lt;li&gt;jobs, the jobs at the restaurant which an employee has&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Regardless of how that data exists we need a way to show it for visitors to our Gatsby site so that's what we will talk about in this post. There are a few steps to get there:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Setting up Gatsby config to use plugins&lt;/li&gt;
&lt;li&gt;Connect Gatsby to Sanity using the API securely
3.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Set up Gatsby Config
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;gatsbyconfig.js&lt;/code&gt; which may need creating on your root folder, and sets up things that apply across your site. The most common things to set up are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Site Metadata - Basic properties of your site&lt;/li&gt;
&lt;li&gt;Plugins - Extra stuff out there to be used. &lt;/li&gt;
&lt;li&gt;Flags - To allow experimental/non-standard features&lt;/li&gt;
&lt;li&gt;Prefix - To set up Gatsby in a particular location on the domain, i.e. for blogs
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;siteMetadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`The Cat and Bear Restaurant`&lt;/span&gt;
    &lt;span class="na"&gt;siteUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`whatever.com`&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Purrfect Food. Roarsome ambiance&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we actually have some data we can head to &lt;code&gt;localhost:8000/___graphql&lt;/code&gt; to build our first query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;query&lt;/span&gt; &lt;span class="nx"&gt;MyQuery&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;site&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;siteMetadata&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;title&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Should return:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;data&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;site&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;siteMetadata&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;The Cat and Bear Restaurant&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;extensions&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Hol' Up, what's this GraphQL stuff?
&lt;/h3&gt;

&lt;p&gt;If you haven't seen graphql before then it. Put simply graphQL can let make queries (reading data) and mutations (changing data) using the syntax that is a little bit like working with JSON (...not really true but best I can do in a sentence.) Its more fun than writing an SQL query at least. &lt;/p&gt;

&lt;p&gt;It will be quite the detour to explain it fully but I can recommend the &lt;a href="https://www.youtube.com/watch?v=Y0lDGjwRYKw"&gt; video series by The Net Ninja&lt;/a&gt; to get the general gist of it. Watch the first few videos at least, I find the visualisations help a lot in making sense of how it works.&lt;/p&gt;

&lt;p&gt;GraphQL is the backbone of how Gatsby handles data so it's important to get it understood.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pluggin' In to Gatsby Plugins
&lt;/h2&gt;

&lt;p&gt;Plugins are a superpower of Gatsby, taking what already exists and hooking it up in your own app. At the time of writing there are 2516 plugs available. You can view the Gatsby Plugin &lt;a href="https://www.gatsbyjs.com/plugins"&gt;Library&lt;/a&gt; to get a flavour of what things are available.&lt;/p&gt;

&lt;p&gt;Adding a plugin is as easy as specifying the name of the plugin:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;siteMetadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`The Cat and Bear Restaurant`&lt;/span&gt;
    &lt;span class="na"&gt;siteUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`whatever.com`&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Purrfect Food. Roarsome ambiance&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;PLUGIN_NAME&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gets it working in the most default manner possible but the documents usually have options we can configure. For the site map plugin we can do something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="c1"&gt;//assume other plugins exist in this array&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`gatsby-plugin-sitemap`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;sitemapSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5000&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Important Note:&lt;/strong&gt; It won't do much till you also &lt;code&gt;npm install&lt;/code&gt; the relevant plug in by its name. &lt;/p&gt;

&lt;p&gt;Getting plugins in Gatsby is a doddle, any complexity will come from the Plugin itself so it will require studying the docs for each one. In my case, we have to get Gatsby talking to Sanity so let's take a deeper look at that:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Deploy graphQL for Sanity. In your Sanity folder type &lt;code&gt;sanity graphql deploy &amp;lt;dataset_name&amp;gt;&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Back in the Gatsby folder, get it installed with &lt;code&gt;npm install gatsby-source-sanity&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Get some details of your Sanity Project. Assuming you have set up a project at (&lt;a href="https://manage.sanity.io/projects/"&gt;https://manage.sanity.io/projects/&lt;/a&gt;) we will need:&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Project ID&lt;/li&gt;
&lt;li&gt;The name of the dataset &lt;/li&gt;
&lt;li&gt;Token. This is a bit more involved. We can create a token by going to 'settings', 'api' and 'add new token'. Give it a label for your own info and copy the long string that appears somewhere. While you are in the API settings, take a mental note that we should specify CORS origins for the URL that will allow us talk to Sanity when it is in production.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`gatsby-source-sanity`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;projectId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&amp;lt;YOUR SANITY PROJECT ID`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&amp;lt;PRODUCTION IN MY CASE&amp;gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;watchMode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;//Allows changes to be reflected in Realtime for development&lt;/span&gt;
        &lt;span class="na"&gt;token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;SANITY_TOKEN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;//DO NOT put you token in here. We need to keep our token secret. So we stick it into a .env file. See below...&lt;/span&gt;

      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  ENV files, to stop ENVious hackers.
&lt;/h3&gt;

&lt;p&gt;Quick aside, API tokens are sensitive, if people have access to them, they can do bad things. Our gatsby-config will be included in version control such as GitHub so we can put the token there. Instead, we just place a reference to an env file that contains secrets and doesn't go into version control. As an aside to our aside, having environment variables is also handly for things that do change between environments, such as connecting to a test database as opposed to a production one, without changing the &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;npm install &lt;code&gt;dotenv&lt;/code&gt; which allows us to use environment files easily&lt;/li&gt;
&lt;li&gt;Create a &lt;code&gt;.env&lt;/code&gt; in the root of our gatsby site.&lt;/li&gt;
&lt;li&gt;Specify what SANITY_TOKEN is:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;SANITY_TOKEN=reg4ergGW...etc&lt;/code&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Lastly we need to configure dotenv in our gatsby config file:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;dotenv&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dotenv&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="nx"&gt;dotenv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.env&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will get the config file using our API Key securely.&lt;/p&gt;

&lt;p&gt;Lastly, we should test it all works, a quick way is to console log the variable (if local) in gatsby-config to see if it is working properly. But if it is all hooked up as intended, when we go to our GraphiQL we should start seeing the contents of our Sanity popping in. Sanity data should start with &lt;code&gt;allSanity&lt;/code&gt; so that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;query&lt;/span&gt; &lt;span class="nx"&gt;MyQuery&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
  &lt;span class="nx"&gt;allSanityMeals&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;nodes&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;name&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Should return all the names of our meals in our hypothetical restaurant site. Phew, the above looks fairly tricky if you have never done something like this before but compared to hooking up a separate backend, I promise, it's a relative breeze!&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Getting it visible via Gatsby Queries
&lt;/h2&gt;

&lt;p&gt;So far we have gotten Gatsby to talk to our Sanity via GraphQL. The last step is getting the data from GraphQL onto our pages. Pretty much the whole reason for two wholly unrelated blog posts. As before all my examples revolve around a hypothetical restaurant site that cares about showing off what it has on its menu.&lt;/p&gt;

&lt;p&gt;In Gatsby, at present, there can are two types of queries we can write to get data into our components and onto the page&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Page Queries. These allow variables but only can be run on a top-level page&lt;/li&gt;
&lt;li&gt;Static Query - Do not allow for variables, but can exist everywhere&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Images are a special bit of data we can look at in more detail.&lt;/p&gt;

&lt;h2&gt;
  
  
  Page Queries
&lt;/h2&gt;

&lt;p&gt;Page queries are pretty straightforward. Here is how we might get the dishes from the database by adding the following GraphQL query to the Food page where we might see all the dishes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;FoodPage&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;This&lt;/span&gt; &lt;span class="nx"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;Food&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;where&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;dishes&lt;/span&gt; &lt;span class="nx"&gt;we&lt;/span&gt; &lt;span class="nx"&gt;serve&lt;/span&gt; &lt;span class="nx"&gt;are&lt;/span&gt; &lt;span class="nx"&gt;listed&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;DishQuery&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;graphql&lt;/span&gt;&lt;span class="s2"&gt;`
  query DishQuery {
    dishes: allSanityDish {        //rename the output something nicer
      edges {
        node {
          id
          name
          price
          intolerences { 
            name
          }
          image {                // We will talk images in a bit
            asset {
              fluid(maxWidth: 400) {
                src
              }
            }
          }
        }
      }
    }
  }
`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;FoodPage&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If that works, you can use React Dev tools to see that the dish data has appeared in props. A good step but let's see if we can manipulate it some more by accessing the props in our code.&lt;/p&gt;

&lt;p&gt;In our FoodPage component we can access the data by passing in the props, or more exactly the data field within props. At this point we can use that data however we like in the component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;FoodPage&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dishes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dishes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;edges&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;We&lt;/span&gt; &lt;span class="nx"&gt;currently&lt;/span&gt; &lt;span class="nx"&gt;serve&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;dishes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;dishes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From there you can build extra components for mapping over the array if you so wish to pass dishes down as props. I won't get into that but if you have worked with React that should be fairly straightforward, here is the component file I ended up with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;DishItem&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;dish&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h2&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;dish&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;dish&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;price&lt;/span&gt;&lt;span class="p"&gt;}{&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt; &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h2&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h3&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Intolerence&lt;/span&gt; &lt;span class="nx"&gt;information&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h3&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;dish&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;intolerences&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;intolerence&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;intolerence&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;, &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)}{&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt; &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;DishList&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;dishes&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;dishes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;dish&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;DishItem&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;dish&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;dish&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;dish&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="p"&gt;))}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;If you have never hooked up a separate backend to a frontend, the above might look a little scary but trust me, compared to most options, the configuration is a breeze. Though I use Sanity, most headless CMSes work on a similar basis bar some syntactical (is that a word?) differences.&lt;/p&gt;

&lt;p&gt;When doing a full stuck app, setting up the conversation between front-end and back end is something I don't enjoy but by breaking it down into smaller steps, it is a bit less scary.&lt;/p&gt;

</description>
      <category>gatsby</category>
      <category>graphql</category>
    </item>
    <item>
      <title>Figuring out Gatsby #4 - A detour to the world of Sanity.</title>
      <dc:creator>Lukie Kang</dc:creator>
      <pubDate>Fri, 18 Dec 2020 15:06:32 +0000</pubDate>
      <link>https://dev.to/neosaurrrus/figuring-out-gatsby-4-a-detour-to-the-world-of-sanity-1i2</link>
      <guid>https://dev.to/neosaurrrus/figuring-out-gatsby-4-a-detour-to-the-world-of-sanity-1i2</guid>
      <description>&lt;p&gt;In my previous posts I have discussed:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Setting up Gatsby&lt;/li&gt;
&lt;li&gt;Making Pages&lt;/li&gt;
&lt;li&gt;Styling those pages&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That is enough for a basic site, but if we need to make something a little more dynamic we need a:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Database to keep data that can be changed&lt;/li&gt;
&lt;li&gt;Way of changing what's in the database&lt;/li&gt;
&lt;li&gt;Way to show what we have in the database on our pages.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The cool kids call this a Backend, and this is something that one can dedicate a whole career to building out. We will not do this, we will use something called Sanity.&lt;/p&gt;

&lt;p&gt;If you like using something else for data, that's cool, Gatsby doesn't really care too hard about what you use but for the app I am building, that's what I will be using. The concepts in later posts are pretty transferable.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the hell is Sanity?
&lt;/h2&gt;

&lt;p&gt;Sanity is a headless CMS. Headless just means that it doesn't have a frontend for users to see what's there, that's what we have Gatsby for. CMS stands for Content Management System which is a system that manages content 😸... fine, it's a tool that handles all ways we can change data, primarily... Create, Read, Update, Delete. AKA CRUD.&lt;/p&gt;

&lt;p&gt;There is a whole bunch of headless CMSes on the market, some cater for simplicity, some for more control. Sanity is a good mix of the two, and the general principles here should work more or less whatever you use.&lt;/p&gt;

&lt;p&gt;In a hypothetical restaurant app, we will have a bunch of dishes on the menu, menus change often. We don't want this to be a hassle, we might even want something that a semi-skilled client could manage without you. This is one reason why having a CMS to make this smooth is a good idea. However, it doesn't mean that setting it up is all that easy. So let's walk through it.&lt;/p&gt;

&lt;h2&gt;
  
  
  How do I get some of this Sanity?
&lt;/h2&gt;

&lt;p&gt;You can probably figure most of it out by following the guidance on the &lt;a href="https://create.sanity.io/"&gt;Sanity Website&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;I am going to focus on getting it up and running via the command line.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1 - Install Sanity CLI and Initialise
&lt;/h3&gt;

&lt;p&gt;This is as simple as typing &lt;code&gt;npm install -g @sanity/cli &amp;amp;&amp;amp; sanity init&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This is will get it installed globally and the second command will initialise a blank Sanity instance in the location you are in.&lt;/p&gt;

&lt;p&gt;You can check it is all version as intended with a &lt;code&gt;sanity --version&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Once you have the starter files up and running, you weirdly should init again...&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2 - Reconfigure
&lt;/h3&gt;

&lt;p&gt;It's time to introduce yourself to Sanity.&lt;/p&gt;

&lt;p&gt;First, type &lt;code&gt;sanity init --reconfigure&lt;/code&gt; and it will prompt you to create an account with Sanity (unless you have done this before). It's a fairly straightforward process that can use GitHub or Google as authentication providers to make it easier.&lt;/p&gt;

&lt;p&gt;Second, give your project a name.&lt;/p&gt;

&lt;p&gt;Thirdly it will ask if you want a private or public dataset and allows you to set up different datasets for testing etc. For your first time stick to the default which sets up a public production dataset but this is important to know for real life.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3 - Intro to Sanity Studio
&lt;/h3&gt;

&lt;p&gt;We have everything set up, so we can type &lt;code&gt;npm start&lt;/code&gt; or &lt;code&gt;sanity start&lt;/code&gt; and if all has gone well it will tell you Sanity is running on localhost:3333. If you open that in your browser, you will be prompted to logon and... &lt;/p&gt;

&lt;p&gt;It will tell you that you have an empty schema. How dull.&lt;/p&gt;

&lt;p&gt;We better go make something to look at here then.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4 - Our first schema
&lt;/h3&gt;

&lt;p&gt;The empty schema message will link to a &lt;a href="https://www.sanity.io/docs/content-modelling"&gt;guide&lt;/a&gt;. This a good step by step guide that provides more detail than I will type here. But I will go over what I did below.&lt;/p&gt;

&lt;p&gt;Since I have a hypothetical restaurant site, I want to store content regarding the dishes that are served. &lt;/p&gt;

&lt;p&gt;In the &lt;code&gt;schemas&lt;/code&gt; folder, I create a new schema called &lt;code&gt;dish.js&lt;/code&gt;. This file exports an object defining what a &lt;em&gt;dish&lt;/em&gt; actually is. Hopefully, it makes sense with my comments:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dish&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// what sanity will know it as&lt;/span&gt;
  &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Dishes&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// what we see it called in Sanity Studio&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;document&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// We will get to this later, document will do for now&lt;/span&gt;
  &lt;span class="na"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="c1"&gt;// what fields does a dish have?&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// What Sanity will know it as&lt;/span&gt;
      &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Dish Name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// What we see it called in Sanity Studio&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// The datatype, this could be lots of things.&lt;/span&gt;
      &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Name of the Dish&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Just explains what the field is.&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once we have the dish schema set up, we need to add it to the overall schema.js file with a &lt;code&gt;import dish from './dish&lt;/code&gt; and modifying the &lt;em&gt;createSchema&lt;/em&gt; object as follows:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;types: schemaTypes.concat([dish]),&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Hopefully, you begin to see how multiple schemas can be built up in this fashion.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5 - Bask in our incredible Back End skills
&lt;/h3&gt;

&lt;p&gt;Let's hop back to Sanity Studio. If all has gone well we can see we have Dishes on the left-hand side. But no content. We can fix that by clicking the new icon in the right-hand side and add our first Dish! &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dGonQgEr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://github.com/neosaurrrus/blog-entries/blob/master/pics/60/1.png%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dGonQgEr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://github.com/neosaurrrus/blog-entries/blob/master/pics/60/1.png%3Fraw%3Dtrue" alt="Fish and Chips" width="800" height="113"&gt;&lt;/a&gt;&lt;br&gt;
Of course, it isn't all that interesting just storing the names of dishes, so once you are happy it works as intended you can delete it via the menu on the bottom right-hand side. &lt;/p&gt;
&lt;h3&gt;
  
  
  Let's make it better!
&lt;/h3&gt;

&lt;p&gt;Well, the possibilities are limitless at this point. The Sanity docs are really good for figuring out how to build upon it but here is what I did:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;check&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;prettier&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dish&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Dishes&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;icon&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;🥣&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Lets give it a cool icon!&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;document&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;//&lt;/span&gt;
  &lt;span class="na"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Dish Name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Name of the Dish&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vegetarian&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Vegetarian&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;boolean&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Is it Vegetarian?&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;layout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;checkbox&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vegan&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Vegan&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;boolean&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Is it Vegan?&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;layout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;checkbox&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;price&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Price&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;number&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Price of dish in pence&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;validation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Rule&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;Rule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;99&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="c1"&gt;// Limits what can be entered for price&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;image&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Dish Image&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;image&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;hotspot&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// clever thing that lets us edit where to focus the picture when resizing&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// Add a slug to deal with pesky spaces in names&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;slug&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;slug&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;slug&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;source&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;maxLength&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;preview&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;select&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;vegetarian&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vegetarian&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;vegan&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vegan&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;prepare&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;
        &lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;vegan&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;- 🌱  Ve&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;vegetarian&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;-🍆 Veg&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt; &lt;span class="c1"&gt;//Nesting Ternaries is a naughty thing to do btw.&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which results in:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZlSY806J--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://github.com/neosaurrrus/blog-entries/blob/master/pics/60/2.png%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZlSY806J--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://github.com/neosaurrrus/blog-entries/blob/master/pics/60/2.png%3Fraw%3Dtrue" alt="Fish and Chips" width="800" height="601"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Starting to look tasty! Note that we:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Added Vegan and Vegetarian Options (and somehow I decided Fish and Chips was vegetarian)&lt;/li&gt;
&lt;li&gt;Added a preview property that lets us get some of the info without having to go into it. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But let's start getting even more clever and look at some related data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Relational Data with a Second Content Type
&lt;/h2&gt;

&lt;p&gt;Ok cool, we have some dishes in our restaurant but we don't want our customers with special dietary requirements to be worried about what we are serving up so we want to capture data around the use of dairy, nuts, gluten. That sort of thing.&lt;/p&gt;

&lt;p&gt;Multiple dishes use dairy products and maybe later we could filter out dairy products from the menu. To do this and save effort in the long run. it needs to exist as a separate content type rather than just be a piece of info buried within each dish.&lt;/p&gt;

&lt;p&gt;A dish can fit many intolerances, i.e it could have Gluten and Shellfish. So we call this a one to many relationships as ONE dish may have MANY ingredients that we care about.&lt;/p&gt;

&lt;p&gt;Ok so first we need a new schema, called &lt;code&gt;intolerance.js&lt;/code&gt; and we want to keep it fairly simple at first:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;intolerance&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Dietary Intolerances&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;icon&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;⚠️&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;document&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Name of the Dietary Tolerance&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Don't forget to add to the schema.js file as before:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;types: schemaTypes.concat([dish, intolerence]),&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Linking it up
&lt;/h3&gt;

&lt;p&gt;Now that we have done that we need to link dishes to their intolerances. This requires us to make an addition to the pizza schema:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Intolerences&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Contains&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;array&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;reference&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;intolerance&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}]&lt;/span&gt; &lt;span class="p"&gt;}],&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So what are we doing here? We are adding an array to our dish schema, and then we are saying that the array will contain &lt;em&gt;references&lt;/em&gt; to our intolerances. This results in the following:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YPNZpwSR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://github.com/neosaurrrus/blog-entries/blob/master/pics/60/3.png%3Fraw%3Dtrue" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YPNZpwSR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://github.com/neosaurrrus/blog-entries/blob/master/pics/60/3.png%3Fraw%3Dtrue" alt="Fish and Chips" width="648" height="171"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Its a bit fiddly in the UI but allows us to link our previously created intolerances to our item. This isn't the most complex data ever for the sake of a short blog post but it's easy to see how this can be developed.&lt;/p&gt;

&lt;p&gt;My final (At least for now) dish schema looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dish&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Dishes&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;icon&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;🥣&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Lets give it a cool icon!&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;document&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;//&lt;/span&gt;
  &lt;span class="na"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Dish Name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Name of the Dish&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vegetarian&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Vegetarian&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;boolean&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Is it Vegetarian?&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;layout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;checkbox&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vegan&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Vegan&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;boolean&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Is it Vegan?&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;layout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;checkbox&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;price&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Price&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;number&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Price of dish in pence&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;validation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Rule&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;Rule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;99&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="c1"&gt;// Limits what can be entered for price&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;image&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Dish Image&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;image&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;hotspot&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// clever thing that lets us edit where to focus the picture when resizing&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// Add a slug to deal with pesky spaces in names&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;slug&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;slug&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;slug&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;source&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;maxLength&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;

    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Intolerences&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Contains&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;array&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;reference&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;intolerance&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}]&lt;/span&gt; &lt;span class="p"&gt;}],&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;preview&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;select&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;vegetarian&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vegetarian&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;vegan&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vegan&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;prepare&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;
        &lt;span class="c1"&gt;// eslint-disable-next-line no-nested-ternary, naughty naughty&lt;/span&gt;
        &lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;vegan&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;- 🌱  Ve&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;vegetarian&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;-🍆  Veg&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Customising our Inputs
&lt;/h2&gt;

&lt;p&gt;One last thing, mostly optional. We are not limited to how Sanity renders the inputs by default. We can make our own version of the inputs using React components, we just need to tell Sanity to do that.&lt;/p&gt;

&lt;h3&gt;
  
  
  The basics
&lt;/h3&gt;

&lt;p&gt;First, we want to create a components folder and inside of that the component we want to use.&lt;/p&gt;

&lt;p&gt;We create a simple React component and import it into the schema as we would in React. In the relevant field object add the following property to tell it to use the component for the input: &lt;/p&gt;

&lt;p&gt;&lt;code&gt;inputComponent: nameOfComponent&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Its a good idea to get a basic component rendering something basic to check it works before moving on.&lt;/p&gt;

&lt;h3&gt;
  
  
  Actually customising the input
&lt;/h3&gt;

&lt;p&gt;There are a few things that are special because we are using Sanity in order for our input to talk to it properly.&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Get Props from Sanity
&lt;/h4&gt;

&lt;p&gt;This is Because we told Sanity that we want to use this component for the input, it gives us a whole bunch of Props we have access to that relate to the data in Sanity. Some key ones are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Type, the filed object, contains the title and description and other things&lt;/li&gt;
&lt;li&gt;Value, what is in the input&lt;/li&gt;
&lt;li&gt;onChange, what to do when it changes&lt;/li&gt;
&lt;li&gt;inputComponent, reference to input itself so Sanity knows what to look at.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  2. Setting up Patching function
&lt;/h4&gt;

&lt;p&gt;Sanity has its own method of updating its data, and it requires some Santity magic as follows:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We import the following:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;import PatchEvent, {set, unset} from 'part:@sanity/form-builder/patch-event'&lt;/code&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Build the following function:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;createPatchFrom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
  &lt;span class="nx"&gt;PatchEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;unset&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Basically, Sanity will set the value if the input value exists and unset it if it does not.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Build our input and complete our component
&lt;/h3&gt;

&lt;p&gt;So I am building an input for an employee's age here, which is a bad idea for real life but for the sake of showing you the whole component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;PatchEvent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="kd"&gt;set&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;unset&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;part:@sanity/form-builder/patch-event&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;createPatchFrom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
  &lt;span class="nx"&gt;PatchEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;unset&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;AgeInput&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;inputComponent&lt;/span&gt; &lt;span class="p"&gt;}){&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h2&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h2&amp;gt;&lt;/span&gt;&lt;span class="err"&gt; 
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;
        &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;onChange&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;createPatchFrom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)})&lt;/span&gt;
        &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;inputComponent&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Phew, if you don't care about Sanity this would be a dull one but since Gatsby doesn't involve itself in backend stuff we need something to handle our data. Sanity is a good pick for something fairly easy to work with and will be used in my posts going forward. &lt;/p&gt;

&lt;p&gt;Next time, we will next get to look at hooking up our Gatsby to our Sanity so we can see the fruits of our hard work on the backend.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
