React4s est une bibliothèque Scala pour l'interface utilisateur du frontend. Il enveloppe la bibliothèque React de Facebook. Il expose une API qui facilite l'écriture de code Scala simple et simple pour vos composants. Vous obtenez gratuitement l'indispensable shouldComponentUpdate() , aucune nomination de rappel requise. Il n'utilise pas de macros, pas implicites et pas de types compliqués.
resolvers += Resolver .sonatypeRepo( " snapshots " )
libraryDependencies += " com.github.ahnfelt " %%% " react4s " % " 0.10.0-SNAPSHOT " case class OkCancel ( label : P [ String ]) extends Component [ Boolean ] {
override def render ( get : Get ) = E .div(
E .div( Text (get(label)),
E .div(
E .button(
Text ( " OK " ),
A .onClick(_ => emit( true ))
),
E .button(
Text ( " Cancel " ),
A .onClick(_ => emit( false ))
)
)
)
} Cela définit un composant OkCancel qui prend une label nommée "prop" de chaîne. Vous lisez les accessoires, l'état, etc. avec l'objet get , qui n'est disponible que là où vous pouvez lire en toute sécurité à partir de ceux-ci. Le Boolean dans Component[Boolean] dit que ce composant émet des messages Boolean , ce qui se fait avec la méthode emit(...) . La méthode render() est ce qui rend votre composant et le composant est réparé automatiquement lorsque les accessoires ou l'état changent. Les objets E , A et S fournissent des méthodes pour construire le DOM virtuel.
Émettre des messages au lieu de prendre des rappels via des accessoires est un écart par rapport à l'API REACT habituel, et c'est comment vous shouldComponentUpdate() gratuitement. Il sépare également clairement l'entrée (accessoires) de la sortie (rappels).
Vous pouvez utiliser un composant comme celui-ci: Component(OkCancel, "Would you like some icecream?") . Le premier argument est l'objet Composants Companion. Les arguments restants sont les accessoires du composant.
case class Counter () extends Component [ NoEmit ] {
val okClicks = State ( 0 )
val cancelClicks = State ( 0 )
def onClick ( ok : Boolean ) = {
if (ok) {
okClicks.modify(_ + 1 )
} else {
cancelClicks.modify(_ + 1 )
}
}
override def render ( get : Get ) = E .div(
Component ( OkCancel , " Would you like some icecream? " ).withHandler(onClick),
E .hr(),
E .div( Text ( " You've clicked OK " + get(okClicks) + " times. " )),
E .div( Text ( " You've clicked Cancel " + get(cancelClicks) + " times. " ))
)
} Le type State permet à la bibliothèque de détecter lorsque vous mettez à jour l'état, afin qu'il puisse réexaminer votre composant. Vous pouvez le lire avec EG. okClicks() et mettez-le à jour avec par exemple. okClicks.set(42) ou okClicks.modify(_ + 1) .
case class OkCancel ( label : P [ String ]) extends Component [ Boolean ] {
override def render ( get : Get ) = E .div(
E .div( Text (get(label)), S .color.rgb( 0 , 0 , 255 )),
E .div(
E .button(
FancyButtonCss ,
Text ( " OK " ),
A .onClick(_ => emit( true ))
),
E .button(
FancyButtonCss ,
Text ( " Cancel " ),
A .onClick(_ => emit( false ))
)
)
)
} Ce qui précède utilise un style en ligne S.color.rgb(0, 0, 255) et une classe CSS FancyButtonCss . La classe CSS est définie comme suit:
object FancyButtonCss extends CssClass (
S .cursor.pointer(),
S .border.px( 2 ).solid().rgb( 0 , 0 , 0 ),
S .color.rgb( 0 , 0 , 0 ),
S .backgroundColor.rgb( 255 , 255 , 255 ),
Css .hover(
S .color.rgb( 255 , 255 , 255 ),
S .backgroundColor.rgb( 0 , 0 , 0 )
)
) Il stylique un bouton pour être blanc avec une bordure noire et noir avec du texte blanc lorsque la souris est en plane dessus. Le <style>...</style> résultant sera ajouté au DOM La première fois que FancyButtonCss est utilisé pour rendre un composant.
object Main extends js. JSApp {
def main () : Unit = {
val component = Component ( Counter )
ReactBridge .renderToDomById(component, " main " )
}
} Créez simplement le composant et appelez renderToDomById . L'argument "main" est l'ID faisant référence à un élément HTML existant, par exemple. <div id="main"></div> .
Dans REACT, vous implémentez shouldComponentUpdate() pour éviter de relancer les composants non apparentés lorsque votre modèle est mis à jour. Dans React4, cette méthode est déjà implémentée pour vous. Il utilise l'opérateur de Scala != Pour vérifier si des accessoires ont changé et met à jour le composant que si les accessoires ont changé ou si l'état a été mis à jour. Cela signifie que pour tout ce qui n'a pas été réaffecté, il compare simplement les références et ne traverse donc pas profondément dans les accessoires.
Méfiez-vous que ce que vous passez via les accessoires doit être immuable et avoir l'égalité structurelle. Vous ne pouvez pas transmettre des objets ou des fonctions mutables comme accessoires, ou vous obtiendrez respectivement une vue obsolète ou une vue lente. Cependant, il est complètement sûr de passer des collections immuables et des classes de cas immuables.
Il s'agit du cycle de vie complet des composants pour React4S. Il est plus simple que la réaction ordinaire car le modèle React4s fait l'hypothèse que vos accessoires sont immuables et ont une égalité structurelle.
Le composant ne sera rejeté que lorsque vos accessoires ont changé, tel que défini par l'inégalité structurelle de Scala != , Ou votre état a été mis à jour. L'état est considéré comme mis à jour lorsque vous avez appelé update() explicitement ou appelé .set(...) ou .modify(...) sur les objets d'état avec une valeur différente de l'opérateur != Opérateur.
Vous pouvez joindre des attaches qui écoutent sur ces événements de cycle de vie, et React4S est livré avec trois de ceux-ci: Timeout , Debounce et Loader . Voyez comment ils sont utilisés dans les exemples en ligne.