JavaScript の基礎
React のコードでよく出てくる JavaScript だけ
ポイント
- React で迷うのは、たいてい React ではなく JavaScript。一覧の関数・比べる記号・書き方の3つに分けて並べた
- map・filter・...(スプレッド)は、元の一覧を変えずに「新しい一覧」を作る。だから React の state と相性がいい
- 知らない書き方は、下の表で「決まり」を1文読んでから、デモで試す
早見表
一覧(配列)の関数
| 書き方 | 決まり(1文) | 例 |
|---|
| .map((x) => …) | 1つずつ取り出して、形を変えた新しい一覧を作る | members.map((m) => <li>{m.name}</li>) |
| .filter((x) => 条件) | 条件に合うものだけを残した新しい一覧を作る | members.filter((m) => m.plan === "有料") |
| .find((x) => 条件) | 条件に合う最初の1つを返す | members.find((m) => m.id === 2) |
| .sort((a, b) => 数) | 2つずつ比べて並び替える。答えがマイナスなら a が前 | [...items].sort((a, b) => a.price - b.price) |
| .slice(始まり, 終わり) | 始まりから、終わりの手前までを切り出す(0 から数える) | items.slice(0, 6) |
| .reduce((合計, x) => …, 0) | 1つずつ見て、1つの値(合計など)にまとめる | items.reduce((sum, i) => sum + i.price, 0) |
| .includes(x) | x が入っているか(true/false) | name.includes(query) |
| .length | 一覧なら個数、文字なら文字数 | {members.length}人 |
| .some((x) => 条件) | 1つでも条件に合うものがあるか(true/false) | items.some((i) => i.stock === 0) |
| .join(区切り) | 一覧を、区切りでつないだ1つの文字にする | tags.join("・") |
比べる・つなぐ
| 書き方 | 決まり(1文) | 例 |
|---|
| === | 左と右が同じか | plan === "有料" |
| !== | 左と右が同じではないか | m.id !== id |
| > >= < <= | より大きい・以上・より小さい・以下 | quantity >= stock |
| ! | 反対にする(true ↔ false) | !isOpen |
| && | かつ。JSX では「合っていれば出す」 | {error && <p>{error}</p>} |
| || | または | !isDirty || isSubmitting |
| 条件 ? A : B | 合っていれば A、違えば B | {open ? "閉じる" : "開く"} |
| a ?? b | a が空っぽ(null・undefined)なら b を使う | user.name ?? "ゲスト" |
| a?.b | a が空っぽでもエラーにせず、undefined にする | user?.name |
書き方
| 書き方 | 決まり(1文) | 例 |
|---|
| (x) => … | 関数を作る(x を受け取って、…する) | () => setCount(count + 1) |
| (x) => { … } | 中に何行も書ける関数 | onClick={() => { reset(); setSent(false) }} |
| const と let | const は入れかえない、let はあとで入れかえる | let sorted = filtered |
| const [a, setA] = … | 返ってきた2つに名前を付けて取り出す | const [count, setCount] = useState(0) |
| const { a, b } = … | 箱({ })の中から、使うものだけ名前で取り出す | const { user } = useAuth() |
| function X({ a }) | 部品に渡されたもの(props)を、名前で受け取る | function Card({ title }) { … } |
| `…${x}…` | 文字の中に、値を入れる(テンプレート文字列) | `${count}件` |
| [...x, 足す] | 一覧をコピーして、最後に足した新しい一覧 | setMembers([...members, newMember]) |
| { ...x, 名札: 値 } | 1つ分をコピーして、1か所だけ変えた新しい1つ分 | { ...member, id: 7 } |
| import/export | ほかのファイルの部品を使う/ほかのファイルに出す | import { Button } from "./button" |
| async/await | 時間のかかること(データの取得など)が終わるのを待つ | const res = await fetch(url) |
試してみよう
import { useState } from "react"
const initialMembers = [
{ id: 1, name: "花子", plan: "有料" },
{ id: 2, name: "一郎", plan: "無料" },
{ id: 3, name: "美咲", plan: "有料" },
]
export default function App() {
const [members, setMembers] = useState(initialMembers)
const [paidOnly, setPaidOnly] = useState(false)
const shown = paidOnly ? members.filter((member) => member.plan === "有料") : members
function addMember() {
const newId = members.length + 1
setMembers([...members, { id: newId, name: "会員" + newId, plan: "無料" }])
}
return (
<div style={{ padding: 16, fontFamily: "sans-serif" }}>
<div style={{ display: "flex", gap: 8 }}>
{}
<button onClick={() => setPaidOnly(!paidOnly)}>{paidOnly ? "全員を見る" : "有料だけ見る"}</button>
<button onClick={() => addMember()}>1人足す</button>
</div>
<p>{shown.length}人</p>
{}
<ul>
{shown.map((member) => (
<li key={member.id}>
{member.name}({member.plan})
</li>
))}
</ul>
</div>
)
}- 「有料だけ見る」を押してみよう(filter で、有料の人だけの新しい一覧ができる)
- "有料" を "無料" に変えてみよう
- 「1人足す」を何回か押してみよう([...members, 新しい人] で、最後に1人ずつ増える)