<?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: Em Whitney</title>
    <description>The latest articles on DEV Community by Em Whitney (@emwhitney).</description>
    <link>https://dev.to/emwhitney</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%2F887583%2Fef95c93a-b000-4f86-9cbf-e65b688bcfa1.jpeg</url>
      <title>DEV Community: Em Whitney</title>
      <link>https://dev.to/emwhitney</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/emwhitney"/>
    <language>en</language>
    <item>
      <title>Elements of Performance</title>
      <dc:creator>Em Whitney</dc:creator>
      <pubDate>Tue, 26 Jul 2022 16:58:00 +0000</pubDate>
      <link>https://dev.to/emwhitney/elements-of-performance-5gjg</link>
      <guid>https://dev.to/emwhitney/elements-of-performance-5gjg</guid>
      <description>&lt;p&gt;These notes are sourced from Web Performance Fundamentals on Front End Masters by Todd Gardner&lt;/p&gt;

&lt;h1&gt;
  
  
  Understanding Performance
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Why is performance important?
&lt;/h2&gt;

&lt;p&gt;The main two reasons are: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;As of 2021, Google ranks you on performance. Performance can make a big difference in whether people see your site on Google search results.&lt;/li&gt;
&lt;li&gt;Angry and frustrated users don't stick around long.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In the real world, a faster load time can increase revenue and conversion rates. &lt;/p&gt;

&lt;h2&gt;
  
  
  What does fast mean?
&lt;/h2&gt;

&lt;p&gt;Websites that feel fast have ads as an afterthought. All the content you want is all there, but later, come the ads. When ads load first, it's distracting and slows down the content of the page. &lt;/p&gt;

&lt;p&gt;Know the psychology of users:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;People want to start&lt;/li&gt;
&lt;li&gt;Bored waits feel slower&lt;/li&gt;
&lt;li&gt;Anxious waits feel slower &lt;/li&gt;
&lt;li&gt;Unexplained waits feel slower (Why am I waiting?)&lt;/li&gt;
&lt;li&gt;Uncertain waits feel slower (How long is this going to take?) &lt;/li&gt;
&lt;li&gt;People will wait for value&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Measuring Web Vitals/Performance
&lt;/h2&gt;

&lt;p&gt;The old way: page load, how long from the time you clicked until the page loaded&lt;br&gt;
The new way: web vitals&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;FCP: first contentful paint&lt;/li&gt;
&lt;li&gt;LCP: largest contentful paint&lt;/li&gt;
&lt;li&gt;CLS: cumulative layout shift&lt;/li&gt;
&lt;li&gt;FID: first input delay&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Google's web master tools measure these values and if you cross over their threshold they'll say they'll reduce your rank if you don't fix the issue&lt;/p&gt;

&lt;h3&gt;
  
  
  FCP: Respond quickly
&lt;/h3&gt;

&lt;p&gt;Time from when the user clicks the link and the first meaningful bit of content enters the page. &lt;/p&gt;

&lt;p&gt;100ms means good performance&lt;br&gt;
300ms means poor performance&lt;/p&gt;

&lt;h3&gt;
  
  
  LCP: get to the point
&lt;/h3&gt;

&lt;p&gt;The time at which the largest percentage of the screen has been rendered gets the LCP. A proxy for when the user thinks the page is almost ready, and most of the page is there. &lt;/p&gt;

&lt;p&gt;2.5s means good performance&lt;br&gt;
4.0s means poor performance&lt;/p&gt;

&lt;h3&gt;
  
  
  CLS: don't move stuff
&lt;/h3&gt;

&lt;p&gt;All the times shifts (pushing the page down as loads come in) happen as the page loads. &lt;/p&gt;

&lt;p&gt;.1 means good performance&lt;br&gt;
.25 means poor performance&lt;/p&gt;

&lt;h3&gt;
  
  
  First Input Delay: don't load too much
&lt;/h3&gt;

&lt;p&gt;Browser time delay between the user's first click and execution of application code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lighthouse: Measuring your performance in Chrome
&lt;/h2&gt;

&lt;p&gt;Lighthouse is a top level tab in dev tools. Lighthouse generates a performance report. Make sure you clear storage and leave throttling on (simulate what a user sees versus what a developer sees).&lt;/p&gt;

&lt;p&gt;Generate report to reload Chrome in the background and produce a performance report. It'll show all the above metrics and a couple more. &lt;/p&gt;

&lt;p&gt;FYI:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Chrome Lighthouse reports are relative to what a user sees&lt;/li&gt;
&lt;li&gt;Shows the performance relative to the Chrome window size so make sure to detatch&lt;/li&gt;
&lt;li&gt;Chrome application priority (make sure Chrome stays in the foreground)&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>TailwindCSS Basics</title>
      <dc:creator>Em Whitney</dc:creator>
      <pubDate>Mon, 11 Jul 2022 16:41:12 +0000</pubDate>
      <link>https://dev.to/emwhitney/tailwindcss-12g5</link>
      <guid>https://dev.to/emwhitney/tailwindcss-12g5</guid>
      <description>&lt;p&gt;&lt;em&gt;These notes were taken while watching the Front End Masters course "Intermediate React, v4" by Brian Holt.&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  What is Tailwind and why use it?
&lt;/h1&gt;

&lt;p&gt;With Tailwind, you write no CSS. Instead, you use small utility classes to style your app.&lt;/p&gt;

&lt;p&gt;All of your CSS lives in your components and classes. This allows you to develop quickly.&lt;/p&gt;

&lt;p&gt;Tailwind is popular in the industry right now, especially with React developers. &lt;/p&gt;

&lt;h1&gt;
  
  
  Installing and setting up Tailwind
&lt;/h1&gt;

&lt;p&gt;Install with npm:&lt;br&gt;
&lt;code&gt;npm i -D tailwindcss@3.0.22 postcss@8.4.6 autoprefixer@10.4.2&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Creating Tailwind configuration document:&lt;br&gt;
&lt;code&gt;npx tailwindcss init&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Modifying configuration document:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;module.exports = {
  mode: "jit",
  content: ["./src/*.{html,js}"],
  theme: {
    extend: {},
  },
  variant: (),
  plugins: [],
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a basic starting config file&lt;/p&gt;

&lt;p&gt;Setting up style.css&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@tailwind base;
@tailwind components;
@tailwind utilities;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is how we include all the things we need from Tailwind. This is what allows Tailwind to bootstrap and only include the CSS you need to make your app run.&lt;/p&gt;

&lt;h1&gt;
  
  
  Basics and gradients
&lt;/h1&gt;

&lt;p&gt;There's a VSCode extension called Tailwind CSS IntelliSense. &lt;/p&gt;

&lt;p&gt;Make a new file in root directory:&lt;br&gt;
&lt;code&gt;.postcssrc&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;And then configure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "plugins": {
    "autoprefixer": {},
    "tailwindcss": {}
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Basics
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// the div right inside &amp;lt;ThemeContext.Provider&amp;gt;
&amp;lt;div
  className="p-0 m-0"
  style={{
    background: "url(http://pets-images.dev-apis.com/pets/wallpaperA.jpg)",
  }}
&amp;gt;
  […]
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;The p-0 and m-0 is what Tailwind is a lot of: putting a lot of tiny utility classes on HTML elements. In this case: we're making it so the encapsulating div has zero padding and zero margin. If we wanted it to have a little of either, it'd m-1 or p-1. There's *-1 through 12 and then there it's more a random increase with 12, 14, 16, 20, 24, 28, 32, 36, 40, etc. all the way up to 96. There's also -m-1 for negative margins. There's also mt, ml, mr, mb for top, left, right, bottom and mx for left and right and my for top and bottom (these all apply to p as well.)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Gradients
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;header className="w-full mb-10 text-center p-7 bg-gradient-to-b from-purple-400 via-pink-500 to-red-500"&amp;gt;
  &amp;lt;Link className="text-6xl text-white hover:text-gray-200" to="/"&amp;gt;
    Adopt Me!
  &amp;lt;/Link&amp;gt;
&amp;lt;/header&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Like p and m, we have w and h. w-1 would have a tiny width. w-full is width: 100%.&lt;/li&gt;
&lt;li&gt;bg-gradient-to-b from-purple-400 via-pink-500 to-red-500 is a gradient just using classes. bg-gradient-to-b says it goes from the top to bottom (you can do -to-l, -to-r, or -to-t as well.) The from is the start. The via is a middle stop, and the to is the end.&lt;/li&gt;
&lt;li&gt;The purple-400 is a purple color and the 400 is the lightness of it. 50 is nearly white, 900 is as dark as the color gets.&lt;/li&gt;
&lt;li&gt;You can set your own colors via the theme but the default ones are really good.&lt;/li&gt;
&lt;li&gt;text-6xl is a really big text size. They use the sizes sm, md, lg, xl, 2xl, etc. up to 9xl.&lt;/li&gt;
&lt;li&gt;text-center will do text-align: center.&lt;/li&gt;
&lt;li&gt;hover: is how we do hover, focus, disabled, etc. It takes whatever is on the right and only applies it only when that state is true. (note: disabled doesn't work without some magic in our PostCSS 7 compat layer. We'll do that in a bit.)&lt;/li&gt;
&lt;li&gt;Note:  from react-router-dom will pass styles and classes down to the resulting &lt;a&gt; for you.&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  CSS Libraries
&lt;/h1&gt;

&lt;p&gt;Emotion and Styled Components are better if you need your JavaScript to managing your CSS a lot (computation of color and hue and saturation computation and things like that). You can then use React to manipulate it. &lt;/p&gt;

&lt;p&gt;You use bootstrap when you need something to look nice but you want to be quick about it.&lt;/p&gt;

&lt;h1&gt;
  
  
  Layout Basics
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div className="my-0 mx-auto w-11/12"&amp;gt;
  &amp;lt;form
    className="p-10 mb-10 rounded-lg bg-gray-200 shadow-lg flex flex-col justify-center items-center"
    onSubmit={(e) =&amp;gt; {
      e.preventDefault();
      requestPets();
    }}
  &amp;gt;
    […]
  &amp;lt;/form&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;rounded-lg is a "large" rounding of the corners i.e. border-radius.&lt;/li&gt;
&lt;li&gt;shadow-lg is a "large" border shadow.&lt;/li&gt;
&lt;li&gt;flex makes the display mode flex. flex-col makes it columns. justify-center makes it justify-content center. items-center makes it align-items: center. Net result is that you have centered horizontally and vertically items in a vertical direction.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Tailwind Plugins
&lt;/h1&gt;

&lt;p&gt;Run npm install -D &lt;a class="mentioned-user" href="https://dev.to/tailwindcss"&gt;@tailwindcss&lt;/a&gt;/&lt;a href="mailto:forms@0.4.0"&gt;forms@0.4.0&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Put this into your tailwind.config.js&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// replace plugins
plugins: [require("@tailwindcss/forms")],
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will apply a bunch of default styles for all of our basic form elements. Tailwind has a pretty great plugin ecosystem. One of my favorites is the aspect-ratio one. CSS doesn't currently have a backwards compatible way of doing aspect ratios (e.g. keep this image in a square ratio) and this plugin makes a primitive that you can use like that.&lt;/p&gt;

&lt;p&gt;With this plugin they (probably wisely) require you to add type="text" to the the input so they can have a good selector for it.&lt;/p&gt;

&lt;p&gt;Let's finish making SearchParams looks nice.&lt;/p&gt;

&lt;p&gt;To each of the selects and inputs, add className="w-60 mb-5 block" so they have a nice uniform look.&lt;/p&gt;

&lt;p&gt;To the breed selector, we want it to be grayed out when it's not available to use.&lt;/p&gt;

&lt;p&gt;Now add className="w-60 mb-5 block disabled:opacity-50" to the breed .&lt;/p&gt;

&lt;p&gt;Replace the button with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;button
  className="rounded px-6 py-2 color text-white hover:opacity-50 border-none"
  style={{ backgroundColor: theme }}
&amp;gt;
  Submit
&amp;lt;/button&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Grid &amp;amp; Breakpoints
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// replace outermost div
&amp;lt;div className="grid gap-4 grid-cols-2"&amp;gt;[…]&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;grid puts you into display: grid.&lt;/li&gt;
&lt;li&gt;gap-4 gives you the gutters between with the number representing how big.&lt;/li&gt;
&lt;li&gt;grid-cols-2 says how many you want per row.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Making it responsive&lt;br&gt;
&lt;code&gt;&amp;lt;div className="grid gap-4 grid-cols-1 sm:grid-cols-2 lg:grid-cols-3"&amp;gt;[…]&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The sm: is the small breakpoint which is larger than 640px apply this style (these can be adjusted and renamed)&lt;/li&gt;
&lt;li&gt;The lg: is the large breakpoint is larger than 1024px. There's also md, xl, and 2xl too.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Positioning
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;Link to={`/details/${id}`} className="relative block"&amp;gt;
  &amp;lt;div&amp;gt;
    &amp;lt;img src={hero} alt={name} /&amp;gt;
  &amp;lt;/div&amp;gt;
  &amp;lt;div className="absolute bottom-0 left-0 bg-gradient-to-tr from-white to-transparent pr-2 pt-2"&amp;gt;
    &amp;lt;h1&amp;gt;{name}&amp;lt;/h1&amp;gt;
    &amp;lt;h2&amp;gt;{`${animal} — ${breed} — ${location}`}&amp;lt;/h2&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/Link&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;We need to set the containing anchor link as both display block and relative positioning so we can reposition inside of it.&lt;/li&gt;
&lt;li&gt;The absolute will make the name tag be absolutely positioned within the relatively positioned parent anchor link.&lt;/li&gt;
&lt;li&gt;bottom-0 and left-0 will put our little name tag in the bottom left of the div.&lt;/li&gt;
&lt;li&gt;The bg-gradient-to-tr from-white to-transparent gives us a fun little white-to-transparent gradient so it makes it easier to read the name tag.&lt;/li&gt;
&lt;li&gt;pr-2 pt-2 is a little right and top padding to extend the gradient.&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>All the React Hooks</title>
      <dc:creator>Em Whitney</dc:creator>
      <pubDate>Wed, 06 Jul 2022 16:43:36 +0000</pubDate>
      <link>https://dev.to/emwhitney/all-the-react-hooks-in-progress-1odn</link>
      <guid>https://dev.to/emwhitney/all-the-react-hooks-in-progress-1odn</guid>
      <description>&lt;p&gt;&lt;em&gt;During my foundational time, I write notes on what I studied and learned.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;These notes were taken while watching the Front End Masters course "Intermediate React, v4" by Brian Holt.&lt;/p&gt;

&lt;h1&gt;
  
  
  Most common hooks
&lt;/h1&gt;

&lt;h2&gt;
  
  
  useState
&lt;/h2&gt;

&lt;p&gt;The useState hook allows us to manage state with functions rather than class components. When state is stored in a hook, the component is loaded on every render and the component always has the latest state. &lt;/p&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;

&lt;p&gt;Used when switching a component between green and not green&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const[isGreen, setIsGreen] = useState(true);

onClick={()=&amp;gt; setIsGreen(!isGreen)}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note: when putting something in the default state, it's preferable that it's something already computed or cheap (true, false, 0, [] etc) rather than a div element, for example. This is a performance consideration since it's not a cheap procedure to create and destroy things like DOM nodes.&lt;/p&gt;

&lt;h2&gt;
  
  
  useEffect
&lt;/h2&gt;

&lt;p&gt;useEffect recreates the componentDidMount, componentDidUpdate, and componentDidUnmount functionality from React. This hook is useful for updates like AJAX requests or third-party library integrations occurring outside the render method.&lt;/p&gt;

&lt;p&gt;If you add an empty array as a dependency, useEffect only runs once. &lt;/p&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;

&lt;p&gt;In this example, the browser displays a timer that updates every second. The page re-renders every second when setTime is changed.&lt;/p&gt;

&lt;p&gt;If you put time in the dependency array, useEffect will run every time the time variable is updated. It's better to be explicit with your dependencies, which is why we're adding time here.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;useEffect(() =&amp;gt; {
  const timer = setTimeout(() =&amp;gt; setTime(new Date()), 1000);
  return () =&amp;gt; clearTimeout(timer);
}, [time]);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  On clearTimeout
&lt;/h3&gt;

&lt;p&gt;clearTimeout takes in whatever the result of setTimeout is it'll prevent the timer you scheduled from running. You do this to clear out the component so you're not calling setTimeout when the component is out of scope (if the component gets unmounted).&lt;/p&gt;

&lt;h2&gt;
  
  
  useContext
&lt;/h2&gt;

&lt;p&gt;Allows data from one component to be available in a subcomponent. This avoids the need to drop drill or pass the data from parent to child. Typically the data used with useContext is application-level state or data that's shared through the entire application.&lt;/p&gt;

&lt;p&gt;Users are an example since you need to read and write user accounts from every part of the application.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;

&lt;p&gt;Passing in userState at the top level and reading it down to a child five levels down. At level five, you use useContext to pull out the original userState hook as user.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;UserContext.Provider value={userState}&amp;gt;
  &amp;lt;h1&amp;gt;first level&amp;lt;/h1&amp;gt;
  &amp;lt;LevelTwo userState={userState} /&amp;gt;
&amp;lt;/UserContext.Provider&amp;gt;;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const LevelFive = () =&amp;gt; {
  const [user, setUser] = useContext(userContext);
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note: use circumventing the normal data flow of React sparingly because it's not as explicit as prop-drilling. It's difficult to debug.&lt;/p&gt;

&lt;h2&gt;
  
  
  useRef
&lt;/h2&gt;

&lt;p&gt;The useRef hook will always return the current value of the object because it is not subject to the closure's scope like useState.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useState, useRef } from "react";

const RefComponent = () =&amp;gt; {
  const [stateNumber, setStateNumber] = useState(0);
  const numRef = useRef(0);

  function incrementAndDelayLogging() {
    setStateNumber(stateNumber + 1);
    numRef.current++;
    setTimeout(
      () =&amp;gt; alert(`state: ${stateNumber} | ref: ${numRef.current}`),
      1000
    );
  }

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;h1&amp;gt;useRef Example&amp;lt;/h1&amp;gt;
      &amp;lt;button onClick={incrementAndDelayLogging}&amp;gt;delay logging&amp;lt;/button&amp;gt;
      &amp;lt;h4&amp;gt;state: {stateNumber}&amp;lt;/h4&amp;gt;
      &amp;lt;h4&amp;gt;ref: {numRef.current}&amp;lt;/h4&amp;gt;
    &amp;lt;/div&amp;gt;
  );
};

export default RefComponent;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why is this useful? It can be useful for things like holding on to setInterval and setTimeout IDs so they can be cleared later.  Or any bit of statefulness that could change but you don't want it to cause a re-render when it does.&lt;/p&gt;

&lt;p&gt;It's also useful for referencing DOM nodes directly and we'll see that a bit later in this section.&lt;/p&gt;

&lt;h2&gt;
  
  
  useReducer
&lt;/h2&gt;

&lt;p&gt;A reducer is passed the state and an action. Based on the action's type, a new state is returned. The useReducer hook uses a dispatcher to call the reducer.&lt;/p&gt;

&lt;p&gt;This is a preferable approach if you have complex state updates or if you have a situation like this: all of the state updates are very similar so it makes sense to contain all of them in one function.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useReducer } from "react";

// fancy logic to make sure the number is between 0 and 255
const limitRGB = (num) =&amp;gt; (num &amp;lt; 0 ? 0 : num &amp;gt; 255 ? 255 : num);

const step = 50;

const reducer = (state, action) =&amp;gt; {
  switch (action.type) {
    case "INCREMENT_R":
      return Object.assign({}, state, { r: limitRGB(state.r + step) });
    case "DECREMENT_R":
      return Object.assign({}, state, { r: limitRGB(state.r - step) });
    case "INCREMENT_G":
      return Object.assign({}, state, { g: limitRGB(state.g + step) });
    case "DECREMENT_G":
      return Object.assign({}, state, { g: limitRGB(state.g - step) });
    case "INCREMENT_B":
      return Object.assign({}, state, { b: limitRGB(state.b + step) });
    case "DECREMENT_B":
      return Object.assign({}, state, { b: limitRGB(state.b - step) });
    default:
      return state;
  }
};

const ReducerComponent = () =&amp;gt; {
  const [{ r, g, b }, dispatch] = useReducer(reducer, { r: 0, g: 0, b: 0 });

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;h1 style={{ color: `rgb(${r}, ${g}, ${b})` }}&amp;gt;useReducer Example&amp;lt;/h1&amp;gt;
      &amp;lt;div&amp;gt;
        &amp;lt;span&amp;gt;r&amp;lt;/span&amp;gt;
        &amp;lt;button onClick={() =&amp;gt; dispatch({ type: "INCREMENT_R" })}&amp;gt;➕&amp;lt;/button&amp;gt;
        &amp;lt;button onClick={() =&amp;gt; dispatch({ type: "DECREMENT_R" })}&amp;gt;➖&amp;lt;/button&amp;gt;
      &amp;lt;/div&amp;gt;
      &amp;lt;div&amp;gt;
        &amp;lt;span&amp;gt;g&amp;lt;/span&amp;gt;
        &amp;lt;button onClick={() =&amp;gt; dispatch({ type: "INCREMENT_G" })}&amp;gt;➕&amp;lt;/button&amp;gt;
        &amp;lt;button onClick={() =&amp;gt; dispatch({ type: "DECREMENT_G" })}&amp;gt;➖&amp;lt;/button&amp;gt;
      &amp;lt;/div&amp;gt;
      &amp;lt;div&amp;gt;
        &amp;lt;span&amp;gt;b&amp;lt;/span&amp;gt;
        &amp;lt;button onClick={() =&amp;gt; dispatch({ type: "INCREMENT_B" })}&amp;gt;➕&amp;lt;/button&amp;gt;
        &amp;lt;button onClick={() =&amp;gt; dispatch({ type: "DECREMENT_B" })}&amp;gt;➖&amp;lt;/button&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  );
};

export default ReducerComponent;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Hooks you're unlikely to use
&lt;/h1&gt;

&lt;h2&gt;
  
  
  useMemo
&lt;/h2&gt;

&lt;p&gt;Memoizes expensive function calls so they are only re-evaluated when needed.&lt;/p&gt;

&lt;p&gt;useMemo and useCallback are performance optimizations. Use them only when you already have a performance problem instead of preemptively. &lt;/p&gt;

&lt;p&gt;useMemo memoizes expensive function calls so they only are re-evaluated when needed. Brian uses the [fibonacci sequence][fibonacci] in its recursive style to simulate this. All you need to know is that once you're calling fibonacci with 30+ it gets quite computationally expensive and not something you want to do unnecessarily as it will cause pauses. It will now only call fibonacci if count changes and will just the previous, memoized answer if it hasn't changed, instead of calling it again on every re-render.&lt;/p&gt;

&lt;p&gt;If we didn't have the useMemo call, every time I clicked on the title to cause the color to change from red to green or vice versa it'd unnecessarily recalculate the answer of fibonacci but because we did use useMemo it will only calculate it when num has changed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useState, useMemo } from "react";

const fibonacci = (n) =&amp;gt; {
  if (n &amp;lt;= 1) {
    return 1;
  }

  return fibonacci(n - 1) + fibonacci(n - 2);
};

const MemoComponent = () =&amp;gt; {
  const [num, setNum] = useState(1);
  const [isGreen, setIsGreen] = useState(true);
  const fib = useMemo(() =&amp;gt; fibonacci(num), [num]);

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;h1
        onClick={() =&amp;gt; setIsGreen(!isGreen)}
        style={{ color: isGreen ? "limegreen" : "crimson" }}
      &amp;gt;
        useMemo Example
      &amp;lt;/h1&amp;gt;
      &amp;lt;h2&amp;gt;
        Fibonacci of {num} is {fib}
      &amp;lt;/h2&amp;gt;
      &amp;lt;button onClick={() =&amp;gt; setNum(num + 1)}&amp;gt;➕&amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
  );
};

export default MemoComponent;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  useCallback
&lt;/h2&gt;

&lt;p&gt;useCallback is similar to useMemo because it will limit calls to expensive functions as long as the props have not changed.&lt;/p&gt;

&lt;p&gt;With useMemo, an expensive function could be called when a component is re-rendered because the function is redeclared. The useCallback hook solves this issue by ensuring the same function is always reference and only called when a re-render is necessary.&lt;/p&gt;

&lt;p&gt;Typically whenever React detects a change higher-up in an app, it re-renders everything underneath it. This normally isn't a big deal because React is quite fast at normal things. However you can run into performance issues sometimes where some components are bad to re-render without reason.&lt;/p&gt;

&lt;p&gt;In this case, Brian is using a new feature of React called React.memo. This is similar to PureComponent where a component will do a simple check on its props to see if they've changed and if not it will not re-render this component (or its children, which can bite you.) React.memo provides this functionality for function components.&lt;/p&gt;

&lt;p&gt;Given that, we need to make sure that the function itself given to ExpensiveComputationComponent is the same function every time. We can use useCallback to make sure that React is handing the same fibonacci to ExpensiveComputationComponent every time so it passes its React.memo check every single time. Now it's only if count changes will it actually re-render (as evidenced by the time.)&lt;/p&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useState, useEffect, useCallback, memo } from "react";

const ExpensiveComputationComponent = memo(({ compute, count }) =&amp;gt; {
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;h1&amp;gt;computed: {compute(count)}&amp;lt;/h1&amp;gt;
      &amp;lt;h4&amp;gt;last re-render {new Date().toLocaleTimeString()}&amp;lt;/h4&amp;gt;
    &amp;lt;/div&amp;gt;
  );
});

const CallbackComponent = () =&amp;gt; {
  const [time, setTime] = useState(new Date());
  const [count, setCount] = useState(1);
  useEffect(() =&amp;gt; {
    const timer = setTimeout(() =&amp;gt; setTime(new Date()), 1000);
    return () =&amp;gt; clearTimeout(timer);
  });

  const fibonacci = (n) =&amp;gt; {
    if (n &amp;lt;= 1) {
      return 1;
    }

    return fibonacci(n - 1) + fibonacci(n - 2);
  };

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;h1&amp;gt;useCallback Example {time.toLocaleTimeString()}&amp;lt;/h1&amp;gt;
      &amp;lt;button onClick={() =&amp;gt; setCount(count + 1)}&amp;gt;
        current count: {count}
      &amp;lt;/button&amp;gt;
      &amp;lt;ExpensiveComputationComponent
        compute={useCallback(fibonacci, [])}
        count={count}
      /&amp;gt;
    &amp;lt;/div&amp;gt;
  );
};

export default CallbackComponent;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  useLayoutEffect
&lt;/h2&gt;

&lt;p&gt;useLayoutEffect is almost the same as useEffect except that it's synchronous to render as opposed to scheduled like useEffect is. If you're migrating from a class component to a hooks-using function component, this can be helpful too because useLayout runs at the same time as componentDidMount and componentDidUpdate whereas useEffect is scheduled after. This should be a temporary fix.&lt;/p&gt;

&lt;p&gt;The only time you should be using useLayoutEffect is to measure DOM nodes for things like animations. In the example, I measure the textarea after every time you click on it (the onClick is to force a re-render.) This means you're running render twice but it's also necessary to be able to capture the correct measurements.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useState, useLayoutEffect, useRef } from "react";

const LayoutEffectComponent = () =&amp;gt; {
  const [width, setWidth] = useState(0);
  const [height, setHeight] = useState(0);
  const el = useRef();

  useLayoutEffect(() =&amp;gt; {
    setWidth(el.current.clientWidth);
    setHeight(el.current.clientHeight);
  });

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;h1&amp;gt;useLayoutEffect Example&amp;lt;/h1&amp;gt;
      &amp;lt;h2&amp;gt;textarea width: {width}px&amp;lt;/h2&amp;gt;
      &amp;lt;h2&amp;gt;textarea height: {height}px&amp;lt;/h2&amp;gt;
      &amp;lt;textarea
        onClick={() =&amp;gt; {
          setWidth(0);
        }}
        ref={el}
      /&amp;gt;
    &amp;lt;/div&amp;gt;
  );
};

export default LayoutEffectComponent;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  useImperativeHandle
&lt;/h2&gt;

&lt;p&gt;Here's one you will likely never directly use but you may use libraries that use it for you. Brian uses it in conjunction with another feature called forwardRef that again, you probably won't use but libraries will use on your behalf. &lt;/p&gt;

&lt;p&gt;In the example above, whenever you have an invalid form, it will immediately focus the the first field that's invalid. If you look at the code, ElaborateInput is a child element so the parent component shouldn't have any access to the input contained inside the component. Those components are black boxes to their parents. All they can do is pass in props. So how do we accomplish it then?&lt;/p&gt;

&lt;p&gt;The first thing we use is useImperativeHandle. This allows us to customize methods on an object that is made available to the parents via the useRef API.&lt;/p&gt;

&lt;p&gt;Inside ElaborateInput we have two refs: one thate is the one that will be provided by the parent, forwarded through by wrapping the ElaborateInput component in a forwardRef call which will ten provide that second ref parameter in the function call, and then the inputRef which is being used to directly access the DOM so we can call focus on the DOM node directly.&lt;/p&gt;

&lt;p&gt;From the parent, we assign via useRef a ref to each of the ElaborateInputs which is then forwarded on each on via the forwardRef. Now, on these refs inside the parent component we have those methods that we made inside the child so we can call them when we need to. In this case, we'll calling the focus when the parent knows that the child has an error.&lt;/p&gt;

&lt;p&gt;Again, you probably use this directly but it's good to know it exists. Normally it's better to not use this hook and try to accomplish the same thing via props but sometimes it may be useful.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useState, useRef, useImperativeHandle, forwardRef } from "react";

const ElaborateInput = forwardRef(
  ({ hasError, placeholder, value, update }, ref) =&amp;gt; {
    const inputRef = useRef();
    useImperativeHandle(ref, () =&amp;gt; {
      return {
        focus() {
          inputRef.current.focus();
        }
      };
    });
    return (
      &amp;lt;input
        ref={inputRef}
        value={value}
        onChange={(e) =&amp;gt; update(e.target.value)}
        placeholder={placeholder}
        style={{
          padding: "5px 15px",
          borderWidth: "3px",
          borderStyle: "solid",
          borderColor: hasError ? "crimson" : "#999",
          borderRadius: "5px",
          margin: "0 10px",
          textAlign: "center"
        }}
      /&amp;gt;
    );
  }
);

const ImperativeHandleComponent = () =&amp;gt; {
  const [city, setCity] = useState("Seattle");
  const [state, setState] = useState("WA");
  const [error, setError] = useState("");
  const cityEl = useRef();
  const stateEl = useRef();

  function validate() {
    // lol I found it on StackOverflow : https://stackoverflow.com/a/25677072
    if (
      !/^([a-zA-Z\u0080-\u024F]+(?:. |-| |'))*[a-zA-Z\u0080-\u024F]+$/.test(
        city
      )
    ) {
      setError("city");
      cityEl.current.focus();
      return;
    }

    if (!/^[A-Z]{2}$/.test(state)) {
      setError("state");
      stateEl.current.focus();
      return;
    }

    setError("");
    alert("valid form!");
  }

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;h1&amp;gt;useImperativeHandle Example&amp;lt;/h1&amp;gt;
      &amp;lt;ElaborateInput
        hasError={error === "city"}
        placeholder={"City"}
        value={city}
        update={setCity}
        ref={cityEl}
      /&amp;gt;
      &amp;lt;ElaborateInput
        hasError={error === "state"}
        placeholder={"State"}
        value={state}
        update={setState}
        ref={stateEl}
      /&amp;gt;
      &amp;lt;button onClick={validate}&amp;gt;Validate Form&amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
  );
};

export default ImperativeHandleComponent;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  useDebugValue &amp;amp; useId
&lt;/h2&gt;

&lt;p&gt;These hooks, like useImperativeHandle, are more built for library authors.&lt;/p&gt;

&lt;p&gt;useDebugValue allows you to surface information from your custom hook into the dev tools. This allows the developer who is consuming your hook (possibly you, possibly your coworker) to have whatever debugging information you choose to surfaced to them. If you're doing a little custom hook for your app (like the breed one we did in the Intro course) this probably isn't necessary. However if you're consuming a library that has hooks (like how react-router-dom has hooks) these can be useful hints to developers.&lt;/p&gt;

&lt;p&gt;Normally you'd just use the developer tools built into the browser but CodeSandbox has the dev tools built directly into it. Just know that normally you'd use the browser extension.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useState, useEffect, useDebugValue } from "react";

const useIsRaining = () =&amp;gt; {
  const [isRaining, setIsRaining] = useState(false);

  useEffect(() =&amp;gt; {
    // pretend here you'd make an API request to a weather API
    // instead we're just going to fake it

    setIsRaining(Math.random() &amp;gt; 0.5);
  }, []);

  useDebugValue(isRaining ? "Is Raining" : "Is Not Raining");

  return isRaining;
};

const DebugValueComponent = () =&amp;gt; {
  const isRaining = useIsRaining();

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;h1&amp;gt;useDebugValue Example&amp;lt;/h1&amp;gt;
      &amp;lt;h2&amp;gt;Do you need a coat today? {isRaining ? "yes" : "maybe"}&amp;lt;/h2&amp;gt;
    &amp;lt;/div&amp;gt;
  );
};

export default DebugValueComponent;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
    <item>
      <title>Portals &amp; useRef in React</title>
      <dc:creator>Em Whitney</dc:creator>
      <pubDate>Tue, 05 Jul 2022 17:37:48 +0000</pubDate>
      <link>https://dev.to/emwhitney/portals-useref-in-react-13k2</link>
      <guid>https://dev.to/emwhitney/portals-useref-in-react-13k2</guid>
      <description>&lt;p&gt;&lt;em&gt;During my foundational time, I'm going to write notes on what I studied and learned.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;These notes were taken while watching the Front End Masters course "Complete Intro to React, v7" by Brian Holt.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a portal?
&lt;/h2&gt;

&lt;p&gt;A portal is a mount point, separate from the actual DOM which the app is put into (root in index HTML), for the React app. &lt;/p&gt;

&lt;p&gt;A common use case for this is a modal (a child window that pops up). &lt;/p&gt;

&lt;h2&gt;
  
  
  Adding the portal
&lt;/h2&gt;

&lt;p&gt;First, add the modal into index.html with a separate mount point&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!-- above #root --&amp;gt;
&amp;lt;div id="modal"&amp;gt;&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Make a new file called Modal.js&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { useEffect, useRef } from "react";
import { createPortal } from "react-dom";

const Modal = ({ children }) =&amp;gt; {
  const elRef = useRef(null);
  if (!elRef.current) {
    elRef.current = document.createElement("div");
  }

  useEffect(() =&amp;gt; {
    const modalRoot = document.getElementById("modal");
    modalRoot.appendChild(elRef.current);
    return () =&amp;gt; modalRoot.removeChild(elRef.current);
  }, []);

  return createPortal(&amp;lt;div&amp;gt;{children}&amp;lt;/div&amp;gt;, elRef.current);
};

export default Modal;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The div container is what renders inside of the Portal. &lt;/p&gt;

&lt;p&gt;Need to render to the portal spot on the DOM.&lt;/p&gt;

&lt;p&gt;Need to remove the div afterwards. You do this by returning a function. This function will get invoked when the Modal goes away. &lt;/p&gt;

&lt;h2&gt;
  
  
  What is a ref?
&lt;/h2&gt;

&lt;p&gt;You use ref when you want to refer to the same thing across all things rendering. &lt;/p&gt;

&lt;p&gt;It is essentially a pointer to an object with a current property, and when you update the ref, you update the current property.&lt;/p&gt;

&lt;p&gt;It will never cause your component to re-render because it is completely separate from the component render cycle, unlike state variables.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding code for modal toggle
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// at the top
import Modal from "./Modal";

// add showModal
state = { loading: true, showModal: false };

// above render
toggleModal = () =&amp;gt; this.setState({ showModal: !this.state.showModal });

// add showModal
const { animal, breed, city, state, description, name, images, showModal } =
  this.state;

// add onClick to &amp;lt;button&amp;gt;
&amp;lt;button onClick={this.toggleModal} style={{ backgroundColor: theme }}&amp;gt;
  Adopt {name}
&amp;lt;/button&amp;gt;;

// below description
{
  showModal ? (
    &amp;lt;Modal&amp;gt;
      &amp;lt;div&amp;gt;
        &amp;lt;h1&amp;gt;Would you like to adopt {name}?&amp;lt;/h1&amp;gt;
        &amp;lt;div className="buttons"&amp;gt;
          &amp;lt;a href="https://bit.ly/pet-adopt"&amp;gt;Yes&amp;lt;/a&amp;gt;
          &amp;lt;button onClick={this.toggleModal}&amp;gt;No&amp;lt;/button&amp;gt;
        &amp;lt;/div&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/Modal&amp;gt;
  ) : null;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
  </channel>
</rss>
