Salut l'ami,
en tant que développeur frontend naïf, je suis entré dans un comportement intéressant:
Sur la base de vos documents, je préfère utiliser React.functionComponent
pour créer des composants car je peux également spécifier le nom du composant pour un meilleur débogage. Une chose drôle vient avec le rafraîchissement de réaction.
Un code comme celui-ci déclenche toujours le rechargement de la page complète lors de toute modification de code:
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 () ]
)
Mais avoir un composant racine avec [<ReactComponent>]
rendra toutes les actualisations fonctionnelles sans faire une actualisation complète.
let subView = React.functionComponent("SubView", fun () ->
Html.text "Hello from sub"
)
[<ReactComponent>]
let topView () = Html.div [ Html.div "Hello from top"; subView () ]
Est-ce un bug? Est-ce un bug dans la fonctionnalité de cravate noire fantaisie? Tout est de ma faute parce que je ne comprends pas la différence entre l'attribut ReactComponent et la fonction React.functionComponent? 😄
Merci pour tout type d'aide pour mieux comprendre.
L'attribut sera la voie à suivre dans le futur et est nécessaire pour que react-refresh fonctionne. Au moins, c'était comme ça, mais je pensais que @ Zaid-Ajaj avait réglé le problème pour qu'il n'y ait aucune différence?
Salut Roman,
C'est une très bonne question à laquelle il n'y a pas de réponse courte, nous y voilà.
Bien qu'une fois que j'aurai réglé mes problèmes Internet à la maison, je reprendrai la diffusion en continu où j'expliquerai cela dans des détails atroces 😁
Sur la base de vos documents, je préfère utiliser
React.functionComponent
pour créer des composants car je peux également spécifier le nom du composant pour un meilleur débogage. Une chose drôle vient avec le rafraîchissement de réaction.
Tout d'abord, je tiens à souligner que la documentation est dans un état de transition malheureux: fondamentalement obsolète avec le dernier Feliz et [<ReactComponent>]
goodness jusqu'à ce que nous résolvions les problèmes de plugin du compilateur et que nous stabilisions l'AST utilisé par Fable . Ce que j'essaie de dire, c'est que les documents ne favorisent React.functionComponent
et si vous utilisez Fable 3, vous devriez commencer à utiliser [<ReactComponent>]
place.
Cela a à voir avec la façon dont le code Javascript est généré. Maintenant, considérez ce morceau de code React:
const App = ({ title }) => {
return (
<h1>{title}</h1>
)
};
<App title="My React Application" />
Ce JS (qui est en fait JSX) se résume au code JS suivant
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" })
Il est très important de noter que l' initialisation du composant App
via <App ... />
est compilée en un appel à createElement
depuis JS.
C'est important à cause de deux choses:
App
d'être une valeur statique (l'identité est réservée dont React utilise)Maintenant, la façon dont React.functionComponent
est implémentée est "mauvaise" pour React car elle combine la définition et la création en une seule fois. Ce code F #
let app React.functionComponent("App", fun (props: {| tite: string |}) -> Html.h1 props.title)
Est en quelque sorte équivalent à dire
let app =
let render(props: {| tite: string |}) =
let renderFn props= Html.h1 props.title
createElement(renderFn , props)
render.displayName <- "App"
render
Maintenant c'est "mauvais" parce que createElement
rend un composant qui est défini dynamiquement à chaque appel et il mute le displayName
de la fonction plutôt que d'utiliser le nom de la fonction lui-même.
Ce sucre de syntaxe utilisé par React.functionComponent
n'affecte pas le comportement d'exécution de React et c'est pourquoi nous pouvons l'utiliser sans problème pour créer l'application React. Les problèmes commencent à disparaître lorsque l' OUTIL autour des applications React commence à analyser le code généré: webpack, babel, react-refresh sont tous des outils qui regardent le code généré, injectent de la magie ici et là pour rendre possible le remplacement de module à chaud mais avec React.functionComponent
ce n'est pas possible car le code généré n'est pas conforme à la façon dont les applications React sont généralement construites lorsque vous écrivez JS et de nombreux outils autour de React font des hypothèses basées sur le fait que le code est écrit selon la norme Réagissez cela que généré par un outil.
La solution à ces problèmes arrive dans Fable 3 où nous sommes autorisés à personnaliser la compilation du code via des plugins de compilateur. Si vous considérez ce code F # Feliz dans Fable 3
[<ReactComponent>]
let app (title: string) = Html.h1 title
app "My React Application"
Ensuite, il compile jusqu'à l'équivalent de ce JS (pas exact car plus de magie)
const App = (props) {
const title = props.title
return createElement("h1", null, title)
}
createElement(App, { title: "My React Application" })
Maintenant, ce code généré est personnalisé pour ressembler à ce que l'outillage React attend:
Cette combinaison fait fonctionner le rafraîchissement de React et, par extension, rend l'expérience de Feliz très proche de celle du JS ou TS natif. J'espère que cela dissipe la confusion. Si vous avez d'autres questions, faites-le moi savoir 😉
Wow! Juste wow! Une personne stupide pose une question stupide et un gars intelligent répond avec trois feuilles A4 pleines d'informations et d'explications pertinentes. 🤯 Tu fais juste du rock, mec! Merci beaucoup! ❤️ Maintenant, je comprends et je vais commencer à utiliser Attribute à la place.
Est-il toujours recommandé de nommer les composants d'une manière ou d'une autre (comme nous l'avons fait en utilisant le premier paramètre de React.functionComponent
) ou ce n'est plus nécessaire pour l'approche attributaire?
Maintenant, je comprends et je vais commencer à utiliser Attribute à la place.
Impressionnant! Permettez-moi si vous rencontrez un problème 😉 pour le moment, le seul problème à prendre en compte est l'utilisation d'un type d' enregistrement comme accessoires d'entrée sera juste un peu problématique pour React-refresh, vous pouvez donc utiliser un enregistrement anonyme à la place ou des paramètres primitifs. J'espère que le problème sera bientôt résolu afin que je puisse documenter [<ReactComponent>]
sans avoir aucune mise en garde.
Est-il toujours recommandé de nommer les composants d'une manière ou d'une autre (comme nous l'avons fait en utilisant le premier paramètre de React.functionComponent) ou ce n'est plus nécessaire pour l'approche attributaire?
Non, la seule exigence est que les composants soient compilés en majuscules, ce qui est l'une des choses que [<ReactComponent>]
fait à la définition de la fonction: smile: vous pouvez l'implémentation ici
@Dzoukr la seule raison d'utiliser des noms pour vos composants de réaction est d'améliorer les outils de débogage.
@Shmew Yup, mais il n'y a pas de surcharge sur le constructeur ReactComponent pour l'ajout d'un tel nom, c'est pourquoi demandé.
Alors, continuez les questions [<ReactComponent>]
vs functionComponent
: hooks!
J'ai un composant qui doit initialiser un état. Heureusement, nous avons de nombreux hameçons fins disponibles! J'écris ceci:
[<ReactComponent>]
let Entrypoint() =
let drawing, updateDrawing = React.useState(Deferred.HasNotStartedYet)
let loader = React.useDeferredCallback((fun () -> loadDrawing()), updateDrawing)
React.useEffect(loader, [||])
// etc
Hélas, quand j'essaye d'exécuter ceci, ma console est triste et pleine d'erreurs:
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
J'ai suivi les étapes de débogage de réaction ci-dessus; aucun ne semble vrai. Cela devrait-il fonctionner? Est-ce une seule chose de Fable 3? (J'utilise toujours Fable 2.)
Je crois comprendre que l'attribut reactcomponent a besoin de fable 3 pour fonctionner car il s'agit d'un plugin de compilateur Fable 3
@landy ah, ça le ferait sûrement. Laisse-moi faire fonctionner Fable 3, je ferai un rapport dans une minute
Hey! Oui, cela m'a corrigé - j'ai utilisé ce PR comme guide pour la conversion.
Commentaire le plus utile
Wow! Juste wow! Une personne stupide pose une question stupide et un gars intelligent répond avec trois feuilles A4 pleines d'informations et d'explications pertinentes. 🤯 Tu fais juste du rock, mec! Merci beaucoup! ❤️ Maintenant, je comprends et je vais commencer à utiliser Attribute à la place.
Est-il toujours recommandé de nommer les composants d'une manière ou d'une autre (comme nous l'avons fait en utilisant le premier paramètre de
React.functionComponent
) ou ce n'est plus nécessaire pour l'approche attributaire?