概要
Reactのコードを書いていて、最適化しようとしてReact.memoを使ったところ、エラーが出てしまいました。memoの使い方を間違えたのかと四苦八苦して解決した際の現象を記事化しました。
React.memoとは
memo を使うことで、props が変更されていない場合にコンポーネントの再レンダーをスキップできます。
変更前のデータをキャッシュしているので、最適化されます。
コードとしては以下となります。
const MemoizedComponent = memo(SomeComponent, arePropsEqual?)
※memoの後ろをカッコで囲う必要あり
エラーコードとメッセージ
const TaskList = memo({ taskList }: Props) => {
return (
<div>
{taskList.map((task) => (
<div
key={task.id}
style={{
width: "300px",
margin: "auto",
background: "lavender",
}}
>
<p>タイトル: {task.title}</p>
<p>担当: {task.assignee}</p>
</div>
))}
</div>
);
};
TS2322: Type '{ taskList: Task[]; }' is not assignable to type 'IntrinsicAttributes & object'.
Property 'taskList' does not exist on type 'IntrinsicAttributes & object'.
79 | リセット
80 | </button>
> 81 | <TaskList taskList={taskList} />
はまった点
- エラーメッセージからコンポーネント呼び出し元で、エラーが発生しているようなので、Propsの渡し方がミスったのかと思ったのですが、どこにも異常が有る訳でも無く...
- 試しに
const TaskList = memo({ taskList }: Props) => {
をconst TaskList = ({ taskList }: Props) => {
とmemoの記載を削除したらエラーが解消される。 - しかし、React.memoを使って最適化しようとしているので、何がおかしいのかと四苦八苦しました。
エラー原因
- 上記[React.memoとは]にも書きましたがmemoの後ろでコンポーネントはカッコで囲う仕様となっています。
- しかし、カッコで囲い忘れていた為でした。正しいコードは次項[正しいコード]となります。
正しいコード
const TaskList = memo(({ taskList }: Props) => {
return (
<div>
{taskList.map((task) => (
<div
key={task.id}
style={{
width: "300px",
margin: "auto",
background: "lavender",
}}
>
<p>タイトル: {task.title}</p>
<p>担当: {task.assignee}</p>
</div>
))}
</div>
);
});
エラー解析にあたって
- ESLint、Prettierは入れていましたが、細かい所まで追ってみるとヒントは出てきました。
- PROBLEMSタブを確認すると、memoの箇所で以下のエラーメッセージが出ていました。
- No overload matches this call.
- エラー解析時は、落ち着いて、エラーメッセージは最後まで読んで解決に当るべきだと思いました。