Heterogenous Arrays & Hooks

In notebook:
FrontEndMasters Intermediate React
Created at:
2019-06-25
Updated:
2019-08-15
Tags:
React libraries JavaScript

https://frontendmasters.com/courses/intermediate-react-v2/heterogenous-arrays-hooks/

do useDropdown

  //    ****        useDropdown.tsx        ****

-import React, { useState } from "react";
+ // **** 1. import extra stuff.  ↴
+import React, { useState, FunctionComponent } from "react";

-const useDropdown = (label, defaultState, options) => {
+function useDropdown(
+  label: string,
+  defaultState: string, // state will always be a string
+  options: string[]
+): [string, () => JSX.Element, (newState: string) => void] {
   const [state, updateState] = useState(defaultState);
   const id = `use-dropdown-${label.replace(" ", "").toLowerCase()}`;
-   const Dropdown = () => (
+   const Dropdown: FunctionComponent = () => (
@@ -23,6 +27,6 @@ const useDropdown = (label, defaultState, options) => {
     </label>
   );
   return [state, Dropdown, updateState];
-};
+}

export default useDropdown;

Doing SearchParams

  rename from src/SearchParams.js
rename to src/SearchParams.tsx
index 759ff45..4bdcd04 100644
--- a/src/SearchParams.js
+++ b/src/SearchParams.tsx
@@ -1,14 +1,20 @@
-import React, { useState, useEffect, useContext } from "react";
-import pet, { ANIMALS } from "@frontendmasters/pet";
+import React, {
+  useState,
+  useEffect,
+  useContext,
+  FunctionComponent
+} from "react";
+import { RouteComponentProps } from "@reach/router";
+import pet, { ANIMALS, Animal } from "@frontendmasters/pet";
 import useDropdown from "./useDropdown";
 import Results from "./Results";
 import ThemeContext from "./ThemeContext";

-const SearchParams = () => {
// we don't need to give this any parameters
+const SearchParams: FunctionComponent<RouteComponentProps> = () => {
   const [theme, setTheme] = useContext(ThemeContext);
   const [location, updateLocation] = useState("Seattle, WA");
-  const [breeds, updateBreeds] = useState([]);
-  const [pets, setPets] = useState([]);
+  const [breeds, updateBreeds] = useState([] as string[]);
+  const [pets, setPets] = useState([] as Animal[]); // an array of Animal
   const [animal, AnimalDropdown] = useDropdown("Animal", "dog", ANIMALS);
   const [breed, BreedDropdown, updateBreed] = useDropdown("Breed", "", breeds);

- return [state, Dropdown]
+ return [state, Dropdown, updateState] as [srting, FunctionComponent, Dispatch<String>]

Mixed or Heterogenous arrays in React

See above the return statement.

TypeScript assumes that the order is not fixed when the list is heterogenous. So you have to define with the as keyword the specific order.

So later, you can use it like so:

const [breed, BreedDropdown, updateBreed] = useDropdown("Breed", "", breeds)

Doing Results.js

  rename from src/Results.js
rename to src/Results.tsx
index 80bcfd4..f59daf8 100644
--- a/src/Results.js
+++ b/src/Results.tsx
@@ -1,7 +1,12 @@
-import React from "react";
+import React, { FunctionComponent } from "react";
+import { Animal } from "@frontendmasters/pet";
 import Pet from "./Pet";

-const Results = ({ pets }) => {
 // **** 1. add the Intreface.  ↴
+interface IProps {
+  pets: Animal[];
+}
+
+const Results: FunctionComponent<IProps> = ({ pets }) => {
   return (
     <div className="search">
       {!pets.length ? (