React4S - это библиотека Scala для пользовательского интерфейса Frontend. Это завершает библиотеку React Facebook. Он разоблачает API, который позволяет легко писать простой и простой код Scala для ваших компонентов. Вы получаете незаменимый shouldComponentUpdate() бесплатно, не требуется заметка обратного вызова. Он не использует макросов, никаких значений и никаких сложных типов.
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 ))
)
)
)
} Это определяет компонент OkCancel , который принимает одну строку «опора» с label . Вы читаете реквизит, состояние и т. Д. С объектом get , который доступен только там, где вы можете безопасно прочитать из них. Boolean в Component[Boolean] говорит, что этот компонент излучает Boolean сообщения, что выполняется с помощью метода emit(...) . Метод render() - это то, что делает ваш компонент, а компонент редернизируется автоматически при изменении реквизита или состояния. Объекты E , A и S предоставляют методы для построения виртуального DOM.
Излучение сообщений вместо того, чтобы принимать обратные вызовы через реквизит, является отходом от обычного API React, и это то, как вы получаете shouldComponentUpdate() бесплатно. Он также явно отделяет вход (реквизиты) от выхода (обратные вызовы).
Вы можете использовать такой компонент, как это: Component(OkCancel, "Would you like some icecream?") . Первый аргумент - это компонент -компаньон. Остальные аргументы являются реквизитом для компонента.
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. " ))
)
} Тип State позволяет библиотеке обнаружить при обновлении состояния, поэтому он может редержать ваш компонент. Вы можете прочитать это с например. okClicks() и обновите его, например. okClicks.set(42) или 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 ))
)
)
)
} Выше используется один встроенный стиль S.color.rgb(0, 0, 255) и один CSS Class FancyButtonCss . Класс CSS определяется следующим образом:
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 )
)
) Это стиляет кнопку, чтобы быть белой с черной границей, и черный с белым текстом, когда мышь парирует над ней. Полученный <style>...</style> будет добавлен в DOM. Первый раз, когда FancyButtonCss используется для отображения компонента.
object Main extends js. JSApp {
def main () : Unit = {
val component = Component ( Counter )
ReactBridge .renderToDomById(component, " main " )
}
} Просто создайте компонент и вызовите renderToDomById . "main" аргументом является идентификатор, относящийся к существующему элементу HTML, например. <div id="main"></div> .
В React вы реализуете shouldComponentUpdate() чтобы избежать обработки не связанных компонентов, когда ваша модель обновляется. В React4s этот метод уже реализован для вас. Он использует оператор Scala != Это означает, что для всего, что не было перераспределено, он просто сравнивает ссылки и, таким образом, не проходит глубоко в реквизит.
Остерегайтесь, что то, что вы проходите через реквизит, должно быть неизбежно и иметь структурное равенство. Вы не можете передавать изменяемые объекты или функции в качестве реквизита, или вы получите несвежие представление или медленный вид соответственно. Тем не менее, совершенно безопасно пройти неизменные коллекции и неизменные занятия.
Это полный жизненный цикл компонента для React4s. Это проще, чем простое реагирование, потому что модель React4S делает предположение, что ваши реквизиты неизменны и имеют структурное равенство.
Компонент будет заменен только тогда, когда ваши реквизиты изменились, как определено структурным неравенством Scala != Или ваше состояние было обновлено. Состояние считается обновлением, когда вы называете update() явно или называется .set(...) или .modify(...) на объектах состояния со значением, которое отличается от предыдущего в соответствии с оператором != .
Вы можете прикрепить Attachables, которые слушают эти события жизненного цикла, и React4s поставляется с тремя из них: Timeout , Debounce и Loader . Посмотрите, как они используются в онлайн -примерах.