ウェブフロント
- angular
- corewebvitals
- editorconfig
- gatsby
- hls
- html
- javascript
querySelectorAllで取得した要素は配列ではないらしい
JavaScript 配列内のオブジェクトの更新ってどうする?
デバッグ関数とかnullチェック関数をutil/index.tsにおいとけば楽なことに今頃気づいた。
ブラウザからジャイロセンサーを使ってみる
JS 画像のアップロード、プレビュー機能を実装
「数値から各桁の値を取り出す処理」って言われたら数学的な処理が一番に思い浮かぶけど、JSならそんなことなかった。
Callback時代の関数をPromise化する
個人的実装されてほしいECMA Script Proposal
JavaScriptのprototypeを使う
音声をなみなみさせる
AudioWorkletとAudioWorkletProcessorを使って音声のビジュアライゼーション
- next
- nuxt
- playwright
- prettier
- react
- reactnative
- tensorflowjs
- tools
- typescript
- wasm
- websocket
- ポエム
- 開発環境
サーバー
その他
useReducerでAPIアクセス
useReducerの使い所
ja.reactjs.org : 複数の値にまたがる複雑なstateロジックがある場合や、前のstateに基づいて次のstateを決める必要がある場合。
APIアクセス結果には、アクセス結果やアクセス状態、エラーの有無など複数の状態があります。
useStateを使って実現しようとすると、
const [result, setResult] = useState({});
const [error, setError] = useState("");
const [status, setStatus] = useState("idle");
のように複数のuseStateが必要になりますが、useRedeucerを使うとまとめて管理できるようになります。
今回はAtCoderのコンテストAPIにリクエストを送ります。
// コンテスト情報の型
interface Contest {
id: string;
title: string;
rate_change: string;
duration_second: number;
start_epoch_second: number;
}
// リクエスト状態
type Status = "idle" | "loading" | "failed" | "success";
// 管理するState
type State = {
contests: Contest[];
error: null | string;
status: Status;
};
// アクションの定義
type Action = {
type: "FETCH_CONTEST";
} | {
type: "FETCH_CONTEST_SUCCESS";
contests: Contest[];
} | {
type: "FETCH_CONTEST_FAILED";
error: string;
};
// reducerの作成
const reducer: Reducer<State, Action> = (state, action) => {
switch (action.type) {
case "FETCH_CONTEST":
return {
...state,
contests: [],
status: "loading",
error: null,
};
case "FETCH_CONTEST_SUCCESS":
return {
...state,
contests: action.contests,
status: "success",
error: null,
};
case "FETCH_CONTEST_FAILED":
return {
...state,
contests: [],
status: "failed",
error: action.error,
};
default:
throw new Error();
}
};
const IndexPage = () => {
// stateとdispatchメソッド、第2引数は初期値
const [state, dispatch] = useReducer(reducer, {
contests: [],
error: null,
status: "idle",
});
useEffect(() => {
// idle状態のときにFETCHを開始
if (state.status === "idle") {
dispatch({ type: "FETCH_CONTEST" });
fetch("https://kenkoooo.com/atcoder/resources/contests.json")
.then((res) => {
if (!res.ok) {
throw new Error(res.statusText);
}
return res.json();
})
.then((res) => {
// 成功した場合
dispatch({
type: "FETCH_CONTEST_SUCCESS",
contests: res,
});
})
.catch((err) => {
// 失敗した場合
dispatch({
type: "FETCH_CONTEST_FAILED",
error: err,
});
});
}
}, []);
return (
<>
// このようにstatusによって簡単に表示を分けることが可能
{state.status === "loading" && <p>Loading...</p>}
{state.status === "success" && <p>{state.contests}</p>}
{state.status === "failed" && <p>{state.error}</p>}
</>
);
};
useStateをつかうよりも状態管理が簡単になりました。
状態管理にflagや条件分岐が増えたときはuseReducerをつかうと良いかもしれません。
Thanks you for reading.