Fable: Conception de l'API React Helper

Créé le 19 mars 2016  ·  3Commentaires  ·  Source: fable-compiler/Fable

Je conçois actuellement une API pour faciliter l'interaction avec React à partir de F# et la combinaison de langues offre plusieurs opportunités intéressantes pour la vérification statique. Cependant, comme prévu, il y a des bouts approximatifs et j'ai des doutes sur la façon de définir les propriétés dans un élément React DOM. Actuellement nous avons :

Option 1 : Propriétés dynamiques

module R = Fable.ReactHelper
R.input [
    "type" ==> "text"
    "placeholder" ==> "Your name"
    "value" ==> x.state.author
    "onChange" ==> x.handleAuthorChange
] []

C'est l'option la plus flexible car nous pouvons transmettre n'importe quelle propriété dans un objet JS simple. Grâce aux fonctions d'inlining, nous n'avons pas besoin d'utiliser createObj ici et nous économisons également quelques accolades. Si vous pensez que le ==> est trop verbeux, le raccourcissement est également trivial : let inline (=>) a b = a ==> b

Le problème est que nous n'avons pas de vérification statique ou de complétion automatique pour les propriétés. J'envisage donc d'utiliser un lambda à la place. Mais maintenant, nous devons décider d'où obtenir la signature. J'ai d'abord pris celui des IntrinsicElements définis dans le fichier de définition React :

Option 2 : Mutation des propriétés HTMLElement

R.input (fun p ->
    p.``type`` <- "text"
    p.placeholder <- "Your name"
    p.value <- unbox x.state.author
    //p.onchange <- unbox x.handleAuthorChange
    p?onChange <- x.handleAuthorChange
) []           

Maintenant, nous avons une vérification statique et une complétion automatique pour les propriétés, ce qui est très agréable. Notez cependant que certaines frictions avec les définitions de type commencent à apparaître et doivent être résolues avec unbox . Le plus gros problème avec cette approche est que, bien que la définition TypeScript utilise les éléments DOM standard, certains attributs ont une orthographe différente dans React. Dans l'exemple ci-dessus, la définition de onchange ne fonctionnera pas, nous devons donc définir onChange manière dynamique. Cela brise presque tous les avantages de la vérification statique :(

Notre prochaine option consiste alors à utiliser React.HTMLAttributes à la place pour être sûr que nous utilisons la bonne orthographe :

Option 3 : Mutation des propriétés React.HTMLAttributes

R.input (fun p ->
    p.``type`` <- Some "text"
    p.placeholder <- Some "Your name"
    p.value <- unbox x.state.author
    p.onChange <- unbox x.handleAuthorChange
) []

Ok, toutes les propriétés ont l'orthographe comme l'attend React mais nous sommes maintenant confrontés à d'autres problèmes : d'abord les frictions avec la signature se multiplient car toutes les propriétés sont définies comme optionnelles et d'autres éléments personnalisés Typescript sont utilisés comme des types d'union effacés ou des fonctions personnalisées ; et deuxièmement, dans l'option précédente, nous avions les attributs spécifiques pour les balises input mais ici, chaque élément HTML partage les mêmes attributs. Cependant, cela peut toujours être la meilleure option.

Il y aurait une quatrième option mais je n'y pense pas beaucoup :

Option 4 : Utilisation d'un enregistrement HTMLAttributes personnalisé

R.input (fun p ->
    { p with
        ``type`` = Some "text"
        placeholder = Some "Your name"
        value = unbox x.state.author
        onChange = unbox x.handleAuthorChange
}) []

Celui-ci est probablement le plus idiomatique en F# mais les règles d'indentation deviennent plus compliquées ( { p with ne peut pas être mis dans la première ligne) et nous n'avons pas de complétion automatique ici pour découvrir les propriétés de p , pour autant que je sache. Plus important encore, adopter ce style nécessiterait de créer un enregistrement personnalisé pour HTMLAttributes car ceux de TypeScript sont analysés comme des interfaces (il y a de bonnes raisons à cela), donc cela ajouterait une étape supplémentaire dans la maintenance de la Fable Fichier

Voici les options pour prendre la décision et j'aimerais entendre votre avis à ce sujet. Je sais qu'il est possible d'ajouter plusieurs options à l'API, mais cela le rendrait probablement plus déroutant pour les nouveaux arrivants et je préférerais faire simple au début. Merci beaucoup pour votre aide d'avance !

discussion

Commentaire le plus utile

Option 5.
Étendre l'option 1. pour ajouter des attributs typés. Je faisais une API similaire pour FunScript à l'époque.
https://github.com/FractalProject/Fractal.Sample/blob/master/client/App.fsx#L65 -L74
https://github.com/FractalProject/Fractal/blob/master/src/Fractal.DOM.fs

Option 6.
Devenez super fou et créez une expression de calcul avec des mots-clés personnalisés.

Tous les 3 commentaires

Option 5.
Étendre l'option 1. pour ajouter des attributs typés. Je faisais une API similaire pour FunScript à l'époque.
https://github.com/FractalProject/Fractal.Sample/blob/master/client/App.fsx#L65 -L74
https://github.com/FractalProject/Fractal/blob/master/src/Fractal.DOM.fs

Option 6.
Devenez super fou et créez une expression de calcul avec des mots-clés personnalisés.

Pour les nouveaux arrivants, je pense que l'option 4 semble être la meilleure, pas non plus de cordes magiques et elle garde les choses immuables.

Merci pour la suggestion, @Krzysztof-Cieslak ! Au début, j'avais peur que cela nécessite plus de travaux d'entretien, mais après réflexion, j'ai réalisé que c'était la meilleure option. J'ai construit sur votre code et écrit un script pour générer (partiellement) le module d'assistance :
https://github.com/fsprojects/Fable/blob/master/samples/browser/react/public/Fable.ReactHelper.fs

Le code de rendu est beaucoup plus joli maintenant avec une vérification statique complète :)
https://github.com/fsprojects/Fable/blob/master/samples/browser/react/public/components.fs#L104 -L124

Il y a encore du travail sur React Helper, mais je ferme le problème pour le moment. Merci à tous pour votre aide!

Cette page vous a été utile?
0 / 5 - 0 notes

Questions connexes

ncave picture ncave  ·  3Commentaires

et1975 picture et1975  ·  3Commentaires

rommsen picture rommsen  ·  3Commentaires

AngelMunoz picture AngelMunoz  ·  4Commentaires

stkb picture stkb  ·  3Commentaires