React + TypeScript コード規約

TypeScript + Reactで作成するアプリケーションのコード規約を備忘録としてまとめます。

概要

この記事では当プロジェクトのコーディング規約について説明する。 随時更新予定。

規約

varを使用しない

varはブロックスコープではなく、また巻き上げ時にundefinedになるため、 let または constを使用する。

// NG var hoge = 'hoge'; // OK let hoge = 'hoge'; const foo = 'foo';

変数名はキャメルケースを使用する

// NG let sample_value = 3; // OK let sampleValue = 3;

非同期処理はasync/awaitを使用する

非同期処理は主にcallback, Promise, async/awaitを使用するパターンがあるが、 Promise.allなど例外を除いて、可読性を上がるためasync/awaitを使用する。

// NG const test = () => { let value; fetch('https://hoge.com').then(res => value = res); } // OK cosnt test = async () => { let value = await fetch('https://hoge.com'); }

コンポーネントは関数コンポーネントを使用する

クラスコンポーネントを使用すると

  • thisを使用する
  • ボイラーテンプレートが増える
  • 状態に関するロジック分離が難しい というデメリットがあるため、例外を除いて関数コンポーネントを使用する。 例外としては error周りのライフサイクルを使用したい場合。
// NG class Hoge { constructor(props) { super(props); this.listRef = React.createRef(); } render() { return ( <div ref={this.listRef}>{/* ...contents... */}</div> ); } // OK const Hoge = () => { const listRef = useRef(); return ( <div ref={this.listRef}>{/* ...contents... */}</div> ); }

重い処理はuseCallbackまたはuseMemoを使用する

関数コンポーネントで重い処理を計算する場合、再描画時または関数呼び出し時に再度呼び出され パフォーマンスへ影響を与えるため、useCallbackまたはuseMemoを使用する。

// NG const value = Array(10000).fill(1).reduce((v, t) => t += v, 100); const hoge = () => Array(10000).fill(1).reduce((v, t) => t += v, 100); // OK const value = useMemo(Array(10000).fill(1).reduce((v, t) => t += v, 100), []); const hoge = useCallback(() => Array(10000).fill(1).reduce((v, t) => t += v, 100), []);

any型は極力使用しない

any型ではすべての型が通ってしまうため、極力 any 型は控える。 代替案としてunknownを使用することを勧める。 unknownはanyと同様に、すべての型が入るが型チェックが発生するため意図しないランタイムエラーを防ぐ。

// NG const value: any = 3; console.log(value.toFixed()); // -> 3 // OK const value: unknown = 3; console.log(value.toFixed()); // Object is of type 'unknown'.

極力イミュータブルにする

イミュータブルにすることで、変数の値が処理中に変更されることを防ぎ、予期せぬバグ・副作用を防ぐ。

// NG interface Model { id: number; name: string; } // OK interface Model { readonly id: number; readonly name: string; }

©Tsurutan. All Rights Reserved.