purity

既知の純粋でない関数を呼び出していないかチェックすることで、コンポーネントやフックが純粋であることを検証します。

ルールの詳細

React コンポーネントは純関数でなければなりません。同じ props が与えられたら、常に同じ JSX を返すべきです。レンダー中に Math.random() や Date.now() などの関数を使うと、毎回異なる出力が生成されるため、React の前提に反し、ハイドレーションの不一致や誤ったメモ化、予測できない動作といったバグを引き起こします。

よくある違反

一般に、同じ入力に対して異なる値を返す API は、このルールに違反します。よくある例は以下のとおりです。

  • Math.random()
  • Date.now() / new Date()
  • crypto.randomUUID()
  • performance.now()

無効な例

このルールに違反するコードの例です。

// ❌ Math.random() in render
function Component() {
const id = Math.random(); // Different every render
return <div key={id}>Content</div>;
}

// ❌ Date.now() for values
function Component() {
const timestamp = Date.now(); // Changes every render
return <div>Created at: {timestamp}</div>;
}

有効な例

このルールに従ったコードの例です。

// ✅ Stable IDs from initial state
function Component() {
const [id] = useState(() => crypto.randomUUID());
return <div key={id}>Content</div>;
}

トラブルシューティング

現在の時刻を表示したい

以下のようにレンダー中に Date.now() を呼び出すと、コンポーネントが純粋ではなくなります。

// ❌ Wrong: Time changes every render
function Clock() {
return <div>Current time: {Date.now()}</div>;
}

代わりに、非純粋な関数はレンダーの外に移動してください。

function Clock() {
const [time, setTime] = useState(() => Date.now());

useEffect(() => {
const interval = setInterval(() => {
setTime(Date.now());
}, 1000);

return () => clearInterval(interval);
}, []);

return <div>Current time: {time}</div>;
}