Open36

Reactの知見を溜め込む

snunsu:<esnunsu:<e

default

default キーワードは、このコードを使用する他のファイルに、これがこのファイルのメイン関数であるということを伝えます。

export default function Square() {
  return <button className="square">X</button>;
}
  • メイン関数の概念があるのか?
snunsu:<esnunsu:<e

この <button> は JSX 要素 (JSX element) と呼ばれます
JSX 要素とは、何を表示したいかを記述するための JavaScript コードと HTML タグの組み合わせ

snunsu:<esnunsu:<e

複数の隣接する JSX 要素は、以下のようにフラグメント(<> および </>)で囲むようにします。

export default function Square() {
  return (
    <>
      <button className="square">X</button>
      <button className="square">X</button>
    </>
  );
}
snunsu:<esnunsu:<e

props

  • 値渡せる
<Square value="1" />

function Square({ value }) {
  return <button className="square">{value}</button>;
}
snunsu:<esnunsu:<e

state

何かを「記憶」するために、コンポーネントは state というものを使用します。

snunsu:<esnunsu:<e

React は、useState という特別な関数を提供しており、コンポーネントからこれを呼び出すことで「記憶」を行わせることができます。

snunsu:<esnunsu:<e

useState

const [value, setValue] = useState(null);
  • useState は現在の状態の値と、その状態を更新するための関数の両方をペアとして返します
  • これを分割代入している
snunsu:<esnunsu:<e

子のstate管理をどうするか

複数の子コンポーネントからデータを収集したい、あるいは 2 つの子コンポーネント同士で通信したい、と思ったら、代わりに親コンポーネントに共有の state を宣言するようにしてください。

snunsu:<esnunsu:<e

何をstateと扱うか

  1. 時間が経っても変わらないものですか? そうであれば、state ではありません。
  2. 親から props 経由で渡されるものですか? そうであれば、state ではありません。
  3. コンポーネント内にある既存の state や props に基づいて計算可能なデータですか?
  4. フィルタリングされた商品のリストは、元の商品リストを検索テキストとチェックボックスの値に従ってフィルタリングすることで計算できるため、state ではありません。
snunsu:<esnunsu:<e

2 種類の “モデル” データ props と state

  • props は関数に渡す引数
  • state はコンポーネントのメモリ
snunsu:<esnunsu:<e

Too many re-renderに注意

  • useState()の値を書き換える処理が初期値も当てはまるとき、レンダリングが無限に起きちゃう
  • || や && を活用して上手く回避してね
snunsu:<esnunsu:<e

props

  • 関数に渡す引数
<Color color="blue" message="mornig" />
const Color = (props) => {
    const {color,message} = props:
    console.log(color); // blue
    console.log(message); // mornig
}
snunsu:<esnunsu:<e

useEffect

  • 第二引数に受け取った変数が変更されたら処理が走る
  • たとえば空の配列を渡すと最初に1回だけ処理が走る
snunsu:<esnunsu:<e

再レンダリングのタイミングの話

  • stateが更新されたコンポーネントは再レンダリング
  • propsが更新されたコンポーネントは再レンダリング
  • 再レンダリングされたコンポーネント配下の子要素は再レンダリング
snunsu:<esnunsu:<e

memoについて

  • 子にmemoを指定することで再レンダリングを防ぐ

https://ja.react.dev/reference/react/memo

新しい props が古い props と同じである限り、親が再レンダーされても React によって再レンダーされないコンポーネントを作成できます。

snunsu:<esnunsu:<e

useCallBackについて

再レンダー間で関数定義をキャッシュできるようにする

https://ja.react.dev/reference/react/useCallback

  • アロー関数は毎回新しい関数を生成されると判定される
  • 故に propsが更新された と判定される
  • それを防ぐためにuseCallBackを使用する
snunsu:<esnunsu:<e

Routingについて

export default function App() {
  return (
    <BrowserRouter>
      <div className="App">
        <Link to="/">Home</Link>
        <br />
        <Link to="/page1">Page1</Link>
        <br />
        <Link to="/page2">Page2</Link>
        <br />
      </div>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/page1" element={<Page1 />} />
        <Route path="/page2" element={<Page2 />} />
      </Routes>
    </BrowserRouter>
  );
}
snunsu:<esnunsu:<e

URLパラメータ

  • useParams();

クエリパラーメータ

  • useLocation();
  • search内にある
  • イメージは下記

<Liink to="/page2/100?name=hoge">

const {search} = useLocation();
const query = new URLSearchParams(search);
console.log(query.get("name")) // hoge

snunsu:<esnunsu:<e

stateを画面遷移で持たせる

<Liink to="/page2/100?name=hoge", state: hoge>

const {state} = useLocation();
snunsu:<esnunsu:<e

Atomic Design

  • React特有の考え方と言うわけではない
段階 説明
アトム (Atoms) UIの基本的な構成要素。ラベル、インプットフィールド、ボタンなどのHTMLタグに相当。
モレキュール (Molecules) アトムが組み合わさってより複合的な機能を持つUIコンポーネント。検索フォームやリストアイテムなど。
オーガニズム (Organisms) モレキュールが組み合わさってさらに複雑なUIセクションを形成。ヘッダー、フッター、プロダクトグリッドなど。
テンプレート (Templates) オーガニズムを含むコンポーネントを配置し、ページのレイアウトを形成するフレームワーク。
ページ (Pages) テンプレートに実際のコンテンツを充填して、実際に動くUIを形成。ユーザーが操作する最終的な画面。
snunsu:<esnunsu:<e
  • 例えば、ボタンはボタンで部品化して使い回す
  • また、ボタンも抽象化できる部分は切り出す
  • 様々なところで汎用的に使いませることがメリット
snunsu:<esnunsu:<e

グローバルstate

グローバルstateのメリット

  • コンポーネント分割し過ぎるとstateを渡していくのが大変!
  • なのでグローバルstateを定義してどこからでも参照できるようにしたらいい!
snunsu:<esnunsu:<e

実現方法

  • 定義する側
import React,{ createContext} from "react";

export const UserContext = createContext({});

export const UserProvider = (props)=>{

  const {children} = props;
  const constName = "しゃけ";
  return(
    <UserProvider.Provider value={{constName}}>
      {children}
    </UserProvider.Provider>
  )
}
  • 使用する側
import { UserContext } from "定義元";

const context = userContext(UserContext);
console.log(context); // {constName: "しゃけ"}


snunsu:<esnunsu:<e

stateを使う場合

import React,{ createContext} from "react";

export const UserContext = createContext({});

export const UserProvider = (props)=>{

  const {children} = props;
  const [userInfo,setUserInfo] = useState(null);
  return(
    <UserProvider.Provider value={{userInfo,setUserInfo}}>
      {children}
    </UserProvider.Provider>
  )
}
snunsu:<esnunsu:<e

TypeScriptについて

let bool: boolean = true;

のように型を指定できる

snunsu:<esnunsu:<e
  • Javaと型の感覚は一緒っぽいので助かる
let arr1: Array<number> = [0,1,2] // 数値型の配列 
let arr2: number[] = [0,1,2] // 数値型の配列
snunsu:<esnunsu:<e

Omit

Constructs a type by picking all properties from Type and then removing Keys (string literal or union of string literals). The opposite of Pick.

Pick<対処の型, "取り除きたいプロパティ">
  • ご察しの通り
snunsu:<esnunsu:<e

オプショナルチェイニング

  • ネストになっている配列がnullでも安全なコードを書く手法
hoge?.fuga
  • hogeがnullならundifindになる
snunsu:<esnunsu:<e

カスタムフックについて

  • stateを隠蔽する手法
  • 呼び出し側も隠蔽したstateの取得もとの挙動を意識せずに呼び出せる