👩💼const Hoge: React.FC<Props>=()=>って書いてたら思考停止系と言われたので調べた2023/02/22に公開2023/02/245件ReactideaDiscussionクロパンダ2023/02/23に更新読んでて気になったのですが、React.FC と FC には差があるので、React.FC を使っていたことを指摘してたのではないでしょうか? というのも JSX を使うために React をインポートしなくて良くなった という背景があります。なので FC ではなく React.FC を使う(=React をインポートする)と tree shaking が効かなくなります。そのことを指摘してた可能性はないでしょうか? あと、react のドキュメントは基本的にコードを JS で書いています。つまり(おそらく) TS 的な都合を考慮したドキュメントになってません。なので、TS + React の時にも function を使うべきかは一考の余地があると思います。 いろいろ書きましたが僕も function については深く考えずアロー関数の優位性を持ってそっちが良いと思ってたので、他の派閥が気になってます。 返信を追加TF2023/02/23Next.js公式でもfunctionですね。他人のコードを読むときに、明示的にfunctionと記述してあると瞬殺でこれは関数であることがわかるから、とどこかで読んだ気がします。 また、Classコンポーネントで実装していた名残で、functionのthisがグローバルのwindowをポイントしていたこともあるかるかもしれません。(つまり、プロジェクトごとに事情は変わる。) 返信を追加Teruhisa - T6ADEV2023/02/23他の方々にも参考になればです。 返信を追加Uhucream2023/02/24「思考停止系エンジニア?」の意図というか真意が分かりませんが、個人的に気になったのは、 const Hoge: React.FC<Props> = () => {} export default Hoge // ここ が気になりました。 export const Hoge: React.FC<Props> = () => {} とも書けますので。 後者の場合、import の際に名前が宣言時の名前と一致する(?)メリットがあります import { Hoge } from '../hoge' 返信を追加Hidden commentHidden commentsmikitky2024/03/30に更新何故かこれ系のほかの記事でも言及されていないことが多いのですが、FC を使う最大の実用上の理由は「FC に返り値の型チェックがあるから」です。コンポーネントとは props を受け取るだけではダメで、ReactNode を return して初めてコンポーネントです。FC はそのチェックを行います。 // 😢これらはコンポーネントではない、オブジェクトを返す謎の関数に過ぎない // …が、エラーにならず定義できてしまう const Hoge = (props: Props) => { return new Date(); }; function Hoge(props: Props) { return new Date(); } // 👍これは書いた瞬間に型エラーになる const Hoge: FC<Props> = () => { return new Date(); } 上側の方法でも実際に JSX 内で使おうとした時点で分かりづらいエラー(要するに「謎の関数を JSX 内で使うな」的なエラー)が出てそこでミスに気づけはします。が、ローカルでコンポーネントを書きながらその場で型エラーが出てくれるのは実用上のメリットです。短いコンポーネントならともかく、条件分岐が含まれた長いコンポーネントではうっかり分岐のどこかで変なことをして、実際に FC の返り値チェックにお世話になることがしばしばあります。 コンポーネント定義時に (props: Props): ReactNode と毎回明示的に返り値の型を書くことで FC と概ね同様の型安全性にはできますし、React コンポーネント程度なら入出力の型を独立して明示的に書いても大したことではありません。が、FC などの関数型は引数と返り値の型を1フレーズで同時にチェックするために存在するので、使えるなら使うべきだと思います。あと厳密には FC は Hoge.displayName が文字列であることなど他の型チェックも行ってくれます。 FC の最大の問題だった暗黙の children は型ファイルの設計ミスの類であって React 18 の時点で修正済なので、2 年以上前の古い記載に基づいて「よう分からんけど FC はダメ」とならないで欲しいなと思っています。 返信を追加
クロパンダ2023/02/23に更新読んでて気になったのですが、React.FC と FC には差があるので、React.FC を使っていたことを指摘してたのではないでしょうか? というのも JSX を使うために React をインポートしなくて良くなった という背景があります。なので FC ではなく React.FC を使う(=React をインポートする)と tree shaking が効かなくなります。そのことを指摘してた可能性はないでしょうか? あと、react のドキュメントは基本的にコードを JS で書いています。つまり(おそらく) TS 的な都合を考慮したドキュメントになってません。なので、TS + React の時にも function を使うべきかは一考の余地があると思います。 いろいろ書きましたが僕も function については深く考えずアロー関数の優位性を持ってそっちが良いと思ってたので、他の派閥が気になってます。 返信を追加
TF2023/02/23Next.js公式でもfunctionですね。他人のコードを読むときに、明示的にfunctionと記述してあると瞬殺でこれは関数であることがわかるから、とどこかで読んだ気がします。 また、Classコンポーネントで実装していた名残で、functionのthisがグローバルのwindowをポイントしていたこともあるかるかもしれません。(つまり、プロジェクトごとに事情は変わる。) 返信を追加
Uhucream2023/02/24「思考停止系エンジニア?」の意図というか真意が分かりませんが、個人的に気になったのは、 const Hoge: React.FC<Props> = () => {} export default Hoge // ここ が気になりました。 export const Hoge: React.FC<Props> = () => {} とも書けますので。 後者の場合、import の際に名前が宣言時の名前と一致する(?)メリットがあります import { Hoge } from '../hoge' 返信を追加
smikitky2024/03/30に更新何故かこれ系のほかの記事でも言及されていないことが多いのですが、FC を使う最大の実用上の理由は「FC に返り値の型チェックがあるから」です。コンポーネントとは props を受け取るだけではダメで、ReactNode を return して初めてコンポーネントです。FC はそのチェックを行います。 // 😢これらはコンポーネントではない、オブジェクトを返す謎の関数に過ぎない // …が、エラーにならず定義できてしまう const Hoge = (props: Props) => { return new Date(); }; function Hoge(props: Props) { return new Date(); } // 👍これは書いた瞬間に型エラーになる const Hoge: FC<Props> = () => { return new Date(); } 上側の方法でも実際に JSX 内で使おうとした時点で分かりづらいエラー(要するに「謎の関数を JSX 内で使うな」的なエラー)が出てそこでミスに気づけはします。が、ローカルでコンポーネントを書きながらその場で型エラーが出てくれるのは実用上のメリットです。短いコンポーネントならともかく、条件分岐が含まれた長いコンポーネントではうっかり分岐のどこかで変なことをして、実際に FC の返り値チェックにお世話になることがしばしばあります。 コンポーネント定義時に (props: Props): ReactNode と毎回明示的に返り値の型を書くことで FC と概ね同様の型安全性にはできますし、React コンポーネント程度なら入出力の型を独立して明示的に書いても大したことではありません。が、FC などの関数型は引数と返り値の型を1フレーズで同時にチェックするために存在するので、使えるなら使うべきだと思います。あと厳密には FC は Hoge.displayName が文字列であることなど他の型チェックも行ってくれます。 FC の最大の問題だった暗黙の children は型ファイルの設計ミスの類であって React 18 の時点で修正済なので、2 年以上前の古い記載に基づいて「よう分からんけど FC はダメ」とならないで欲しいなと思っています。 返信を追加
Discussion
読んでて気になったのですが、React.FC と FC には差があるので、React.FC を使っていたことを指摘してたのではないでしょうか?
というのも JSX を使うために React をインポートしなくて良くなった という背景があります。なので FC ではなく React.FC を使う(=React をインポートする)と tree shaking が効かなくなります。そのことを指摘してた可能性はないでしょうか?
あと、react のドキュメントは基本的にコードを JS で書いています。つまり(おそらく) TS 的な都合を考慮したドキュメントになってません。なので、TS + React の時にも function を使うべきかは一考の余地があると思います。
いろいろ書きましたが僕も function については深く考えずアロー関数の優位性を持ってそっちが良いと思ってたので、他の派閥が気になってます。
Next.js公式でもfunctionですね。他人のコードを読むときに、明示的にfunctionと記述してあると瞬殺でこれは関数であることがわかるから、とどこかで読んだ気がします。
また、Classコンポーネントで実装していた名残で、functionのthisがグローバルのwindowをポイントしていたこともあるかるかもしれません。(つまり、プロジェクトごとに事情は変わる。)
他の方々にも参考になればです。
「思考停止系エンジニア?」の意図というか真意が分かりませんが、個人的に気になったのは、
が気になりました。
とも書けますので。
後者の場合、
importの際に名前が宣言時の名前と一致する(?)メリットがあります何故かこれ系のほかの記事でも言及されていないことが多いのですが、
FCを使う最大の実用上の理由は「FCに返り値の型チェックがあるから」です。コンポーネントとは props を受け取るだけではダメで、ReactNodeを return して初めてコンポーネントです。FCはそのチェックを行います。上側の方法でも実際に JSX 内で使おうとした時点で分かりづらいエラー(要するに「謎の関数を JSX 内で使うな」的なエラー)が出てそこでミスに気づけはします。が、ローカルでコンポーネントを書きながらその場で型エラーが出てくれるのは実用上のメリットです。短いコンポーネントならともかく、条件分岐が含まれた長いコンポーネントではうっかり分岐のどこかで変なことをして、実際に
FCの返り値チェックにお世話になることがしばしばあります。コンポーネント定義時に
(props: Props): ReactNodeと毎回明示的に返り値の型を書くことでFCと概ね同様の型安全性にはできますし、React コンポーネント程度なら入出力の型を独立して明示的に書いても大したことではありません。が、FCなどの関数型は引数と返り値の型を1フレーズで同時にチェックするために存在するので、使えるなら使うべきだと思います。あと厳密にはFCはHoge.displayNameが文字列であることなど他の型チェックも行ってくれます。FCの最大の問題だった暗黙のchildrenは型ファイルの設計ミスの類であって React 18 の時点で修正済なので、2 年以上前の古い記載に基づいて「よう分からんけどFCはダメ」とならないで欲しいなと思っています。