Feliz: [<reactcomponent>] vsReactリフレッシュのReact.functionComponent</reactcomponent>

作成日 2020年11月25日  ·  10コメント  ·  ソース: Zaid-Ajaj/Feliz

こんにちは友人、

素朴なフロントエンド開発者として、私は興味深い行動を取りました。

ドキュメントに基づいて、コンポーネントの作成にReact.functionComponentを使用することをお勧めします。これは、コンポーネントの名前を指定して、デバッグを改善することもできるためです。 面白いことに、reactrefreshが付属しています。

このようなコードは、コードに変更を加えると、常にページ全体のリロードをトリガーします。

let subView = React.functionComponent("SubView", fun () ->
    Html.text "Hello from sub"
)

let topView = React.functionComponent("TopView", fun () ->
    Html.div [ Html.div "Hello from top"; subView () ]
)

image

ただし、ルートコンポーネントに[<ReactComponent>]が含まれていると、完全な更新を行わなくてもすべての更新が正常に機能します。

let subView = React.functionComponent("SubView", fun () ->
    Html.text "Hello from sub"
)

[<ReactComponent>]
let topView () = Html.div [ Html.div "Hello from top"; subView () ]

バグですか? それは派手な黒のネクタイ別名機能のバグですか? ReactComponent属性とReact.functionComponent関数の違いがわからないので、それはすべて私のせいですか? 😄

理解を深めるためのあらゆる種類の支援に感謝します。

question

最も参考になるコメント

うわー! ただ...すごい! 愚かな人は愚かな質問をし、賢い人は関連情報と説明が満載の3枚のA4シートで答えます。 🤯あなたはただロックします、男! どうもありがとう! ❤️これで理解でき、代わりにAttributeの使用を開始します。

なんらかの方法でコンポーネントに名前を付けることをお勧めしますか( React.functionComponentの最初のパラメーターを使用したように)、これは属性アプローチではもう必要ありませんか?

全てのコメント10件

この属性は将来の道であり、react-refreshが機能するために必要です。 少なくとも、そうだったのですが、@ Zaid-Ajajがそれを整理して、違いがないようにしたと思いましたか?

こんにちはローマン、

これは本当に良い質問であり、短い答えはありません。ここに行きます。

自宅でインターネットの問題を解決したら、ストリーミングを再開します。ここで、これを非常に詳細に説明します😁

ドキュメントに基づいて、コンポーネントの作成にReact.functionComponentを使用することをお勧めします。これは、デバッグを改善するためにコンポーネントの名前を指定することもできるためです。 面白いことに、reactrefreshが付属しています。

まず、ドキュメントが不幸な移行状態にあることを指摘したいと思います。コンパイラプラグインの問題を整理し、Fableで使用されるASTを安定させるまで、基本的に最新のFelizと[<ReactComponent>]良さで時代遅れです。 。 私が言おうとしているのは、ドキュメントReact.functionComponentを支持しておらず、Fable 3を使用している場合は、代わりに[<ReactComponent>]使用を開始する必要があるということです。

これは、Javascriptコードの生成方法と関係があります。 ここで、このReactコードについて考えてみましょう。

const App = ({ title }) => {
  return (
    <h1>{title}</h1>
  )
};

<App title="My React Application" />

このJS(実際にはJSX)は、次のJSコードにデシュガーダウンします

import { createElement } from 'react'

const App = ({ title }) => {
  return createElement("h1", null, title);
};

// <App /> compiles to a call to createElement
createElement(App, { title: "My React Application" })

<App ... />を介したAppコンポーネントの初期化は、JSからcreateElementへの呼び出しにコンパイルされることに注意することが非常に重要です。

それは2つの理由で重要です:

  • コンポーネントの定義をその作成から分離します
  • Appを静的な値にすることができます(Reactが使用するIDは予約されています)

現在、 React.functionComponent実装方法は、定義と作成を一度に組み合わせるため、Reactにとって「悪い」ものです。 このF#コード

let app React.functionComponent("App", fun (props: {|  tite: string |}) -> Html.h1 props.title)

言うのと同じようなものです

let app = 
  let render(props: {|  tite: string |}) = 
    let renderFn props= Html.h1 props.title
    createElement(renderFn , props)
  render.displayName <- "App"
  render

createElementは、呼び出しごとに動的に定義されるコンポーネントをレンダリングし、関数名自体を使用するのではなく、関数のdisplayNameを変更するため、これは「悪い」です。

React.functionComponent採用するこの構文糖衣は、Reactの実行時の動作に影響を与えません。そのため、Reactアプリケーションを問題なく使用できます。 WebPACKの、バベル、反応リフレッシュここにいくつかの魔法を注入し、可能なホットモジュールの交換が作るするしかし、すべての生成されたコードを見てツールです:ツーリングの周りに生成されたコードを解析するためのアプリケーションが起動し反応すると問題が出てクリープを開始しますReact.functionComponent生成されたコードは、JSを作成するときにReactアプリケーションが通常構築される方法に準拠しておらず、Reactを取り巻くツールの多くは、コードが標準に従って作成されているという事実に基づいて仮定しているため、不可能ですツールによって生成されるよりもそれを反応させます。

これらの問題の解決策は、コンパイラプラグインを介してコードのコンパイルをカスタマイズできるFable3で提供されます。 Fable 3でこのF#Felizコードを検討する場合

[<ReactComponent>]
let app (title: string) = Html.h1 title 

app "My  React Application"

次に、このJSと同等のものにコンパイルされます(より多くの魔法があるため正確ではありません)

const App = (props) { 
   const title = props.title
   return createElement("h1", null, title)
}

createElement(App, { title: "My  React Application" })

これで、この生成されたコードは、Reactツールが期待するもののようにカスタマイズされます。

  • 関数コンポーネントの定義と作成は別々です
  • コンポーネントは大文字として定義されます(はい、これも必要であり、コンパイラプラグインは自動的に定義を書き換えます)
  • 入力パラメータは自動的にReact小道具に変換されます

この組み合わせにより、Reactの更新が機能し、ひいてはFelizのエクスペリエンスがネイティブのJSまたはTSのエクスペリエンスに非常に近くなります。 これで混乱が解消されることを願っています。 他にご不明な点がございましたら、お気軽にお問い合わせください😉

うわー! ただ...すごい! 愚かな人は愚かな質問をし、賢い人は関連情報と説明が満載の3枚のA4シートで答えます。 🤯あなたはただロックします、男! どうもありがとう! ❤️これで理解でき、代わりにAttributeの使用を開始します。

なんらかの方法でコンポーネントに名前を付けることをお勧めしますか( React.functionComponentの最初のパラメーターを使用したように)、これは属性アプローチではもう必要ありませんか?

これで理解でき、代わりにAttributeの使用を開始します。

驚くばかり! 問題が発生した場合は、私に知らせてください😉現時点で注意すべき唯一の問題は、入力小道具がReact-refreshで少し問題になるため、レコードタイプを使用することです。そのため、代わりに匿名レコードまたはプリミティブパラメーターを使用できます。 この問題がすぐに修正され、警告なしに[<ReactComponent>]を文書化できるようになることを願っています。

(React.functionComponentの最初のパラメーターを使用したように)何らかの方法でコンポーネントに名前を付けることをお勧めしますか、それとも属性アプローチではもう必要ありませんか?

いいえ、唯一の要件は、コンポーネントが大文字の値としてコンパイルされることです。これは、 [<ReactComponent>]が関数定義に対して行うことの1つです:smile:ここで実装でき

@Dzoukrがreactコンポーネントに名前を使用する唯一の理由は、デバッグツールを改善することです。

@Shmewうん、でもそのような名前を追加するためのReactComponentコンストラクターにはオーバーロードがないので、それが尋ねられる理由です。

したがって、 [<ReactComponent>]functionComponent質問を続ける:フック!

いくつかの状態を初期化する必要があるコンポーネントがあります。 幸いなことに、私たちは多くの素晴らしいフックを利用できます! 私はこれを書きます:

[<ReactComponent>]
let Entrypoint() =
    let drawing, updateDrawing = React.useState(Deferred.HasNotStartedYet)
    let loader = React.useDeferredCallback((fun () -> loadDrawing()), updateDrawing)

    React.useEffect(loader, [||])
    // etc

残念ながら、これを実行しようとすると、コンソールが悲しく、エラーでいっぱいになります。

Uncaught Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
See https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.
    React 

上記のreactデバッグ手順を実行しました。 どれも真実ではないようです。 これは機能するはずですか? これはFable3だけですか? (私はまだFable 2を使用しています。)

私の理解では、reactcomponent属性はfable 3コンパイラプラグインであるため、機能するにはfable3が必要です。

@landyああ、それは確かにそれをするだろう。 LemmeはFable3を動作させ、すぐに報告します

ねえ! うん、それは私を直した-私は変換のガイドとしてこのPRを使用した。

このページは役に立ちましたか?
0 / 5 - 0 評価