JavaScript basics

Just the JavaScript that shows up often in React code

Key points

  • When you get stuck in React, it's usually JavaScript, not React. Here it's sorted into three groups: array functions, comparison symbols, and syntax
  • map, filter, and ... (spread) don't change the original array — they make a "new array". That's why they work so well with React state
  • For syntax you don't know, read the one-sentence "rule" in the table below, then try it in the demo

Cheat sheet

Array functions

SyntaxRule (in one sentence)Example
.map((x) => …)Takes items one at a time and makes a new array of reshaped itemsmembers.map((m) => <li>{m.name}</li>)
.filter((x) => condition)Makes a new array with only the items that match the conditionmembers.filter((m) => m.plan === "Paid")
.find((x) => condition)Returns the first item that matches the conditionmembers.find((m) => m.id === 2)
.sort((a, b) => number)Compares two at a time to reorder. If the result is negative, a comes first[...items].sort((a, b) => a.price - b.price)
.slice(start, end)Cuts out from start up to just before end (counting from 0)items.slice(0, 6)
.reduce((total, x) => …, 0)Looks at each item and combines them into one value (such as a total)items.reduce((sum, i) => sum + i.price, 0)
.includes(x)Whether x is in it (true / false)name.includes(query)
.lengthThe number of items for an array, the number of characters for a string{members.length} members
.some((x) => condition)Whether even one item matches the condition (true / false)items.some((i) => i.stock === 0)
.join(separator)Turns an array into one string, joined with the separatortags.join(", ")

Comparing and combining

SyntaxRule (in one sentence)Example
===Whether left and right are the sameplan === "Paid"
!==Whether left and right are not the samem.id !== id
> >= < <=Greater than, greater than or equal, less than, less than or equalquantity >= stock
!Flips it (true ↔ false)!isOpen
&&And. In JSX, "show it if it's true"{error && <p>{error}</p>}
||Or!isDirty || isSubmitting
condition ? A : BA if it's true, B if not{open ? "Close" : "Open"}
a ?? bIf a is empty (null or undefined), use buser.name ?? "Guest"
a?.bIf a is empty, gives undefined instead of an erroruser?.name

Syntax

SyntaxRule (in one sentence)Example
(x) => …Makes a function (takes x and does …)() => setCount(count + 1)
(x) => { … }A function that can have many lines insideonClick={() => { reset(); setSent(false) }}
const and letconst is never reassigned; let can be reassigned laterlet sorted = filtered
const [a, setA] = …Gives names to the two things returned and takes them outconst [count, setCount] = useState(0)
const { a, b } = …Takes out only what you need from the box ({ }), by nameconst { user } = useAuth()
function X({ a })Receives what was passed to the component (props), by namefunction Card({ title }) { … }
`…${x}…`Puts a value inside a string (template literal)`${count} items`
[...x, extra]A new array that copies the array and adds something at the endsetMembers([...members, newMember])
{ ...x, key: value }A new object that copies the object and changes just one field{ ...member, id: 7 }
import / exportUse a component from another file / make it available to other filesimport { Button } from "./button"
async / awaitWaits for something slow (like fetching data) to finishconst res = await fetch(url)

Try it

import { useState } from "react"

// The member list (the first 3 people)
const initialMembers = [
  { id: 1, name: "Emma", plan: "Paid" },
  { id: 2, name: "Liam", plan: "Free" },
  { id: 3, name: "Olivia", plan: "Paid" },
]

export default function App() {
  // The member list (grows with "Add one")
  const [members, setMembers] = useState(initialMembers)
  // Whether "Paid only" is on (true = on)
  const [paidOnly, setPaidOnly] = useState(false)

  // The list to show: only paid members if it's on, everyone if it's off
  const shown = paidOnly ? members.filter((member) => member.plan === "Paid") : members

  // Add one: line up all current members and add one new person at the end
  function addMember() {
    const newId = members.length + 1
    setMembers([...members, { id: newId, name: "Member " + newId, plan: "Free" }])
  }

  return (
    <div style={{ padding: 16, fontFamily: "sans-serif" }}>
      <div style={{ display: "flex", gap: 8 }}>
        {/* Each click switches between paid only ↔ everyone (! = flip it) */}
        <button onClick={() => setPaidOnly(!paidOnly)}>{paidOnly ? "Show everyone" : "Paid only"}</button>
        <button onClick={() => addMember()}>Add one</button>
      </div>
      <p>{shown.length} members</p>
      {/* Turn each person in the list to show into a "Name (plan)" row */}
      <ul>
        {shown.map((member) => (
          <li key={member.id}>
            {member.name} ({member.plan})
          </li>
        ))}
      </ul>
    </div>
  )
}
  1. Click "Paid only" (filter makes a new array with only the paid members)
  2. Change "Paid" to "Free"
  3. Click "Add one" a few times ([...members, newPerson] adds one person at the end each time)

Common pitfalls

members.push(person) doesn't update the screen
push just rewrites the original array, so React doesn't notice anything changed. Make a new array with [...members, person] and pass it to setMembers.
.sort rewrites the original array
Unlike map and filter, sort reorders the original array itself. Copy it first, then sort: [...items].sort(…).
= means "put in", === means "is it the same?"
If you write = in a condition, it puts the value in instead of comparing. To compare, use ===.