You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -140,24 +138,24 @@ Replace the code in the `Main.kt` file as follows:
140
138
```kotlin
141
139
importkotlinx.browser.document
142
140
importreact.*
143
-
importreact.css.css
144
-
importreact.dom.render
141
+
importemotion.react.css
145
142
importcsstype.Position
146
143
importcsstype.px
147
144
importreact.dom.html.ReactHTML.h1
148
145
importreact.dom.html.ReactHTML.h3
149
146
importreact.dom.html.ReactHTML.div
150
147
importreact.dom.html.ReactHTML.p
151
148
importreact.dom.html.ReactHTML.img
149
+
importreact.dom.client.createRoot
152
150
importkotlinx.serialization.Serializable
153
151
154
152
funmain() {
155
153
val container = document.getElementById("root") ?: error("Couldn't find root container!")
156
-
render(Fragment.create {
154
+
createRoot(container).render(Fragment.create {
157
155
h1 {
158
156
+"Hello, React+Kotlin/JS!"
159
157
}
160
-
}, container)
158
+
})
161
159
}
162
160
```
163
161
{validate="false"}
@@ -167,7 +165,7 @@ fun main() {
167
165
This element is a container defined in `src/main/resources/index.html`, which was included in the template.
168
166
* The content is an `<h1>` header and uses a typesafe DSL to render HTML.
169
167
*`h1` is a function that takes a lambda parameter. When you add the `+` sign in front of the string literal,
170
-
the `unaryPlus()` function is actually invoked using [operator overloading](https://kotlinlang.org/docs/reference/operator-overloading.html).
168
+
the `unaryPlus()` function is actually invoked using [operator overloading](operator-overloading.md).
171
169
It appends the string to the enclosed HTML element.
172
170
173
171
When the project recompiles, the browser displays this HTML page:
@@ -177,7 +175,7 @@ When the project recompiles, the browser displays this HTML page:
177
175
### Convert HTML to Kotlin
178
176
179
177
The Kotlin [wrappers](https://github.com/JetBrains/kotlin-wrappers/blob/master/kotlin-react/README.md) for React come
180
-
with a [domain-specific language (DSL)](https://kotlinlang.org/docs/type-safe-builders.html) that allows writing HTML in
178
+
with a [domain-specific language (DSL)](type-safe-builders.md) that allows writing HTML in
181
179
pure Kotlin code. In this way, it's similar to [JSX](https://reactjs.org/docs/introducing-jsx.html) from JavaScript.
182
180
However, with this markup being Kotlin, you get all the benefits of a statically typed language, such as autocomplete or type checking.
183
181
@@ -305,23 +303,23 @@ sure that the loop is working.
305
303
306
304
### Add styles with typesafe CSS
307
305
308
-
The [kotlin-react-css](https://github.com/JetBrains/kotlin-wrappers/tree/master/kotlin-react-css) library allows specifying
309
-
CSS attributes – even dynamic ones – right alongside HTML. Conceptually, that makes it similar to
310
-
[CSS-in-JS](https://reactjs.org/docs/faq-styling.html#what-is-css-in-js) – but for Kotlin. The benefit of using a DSL is
311
-
that you can use Kotlin code constructs to express formatting rules.
306
+
The [kotlin-emotion](https://github.com/JetBrains/kotlin-wrappers/blob/master/kotlin-emotion/) wrapper for the [Emotion](https://emotion.sh/docs/introduction)
307
+
library allows specifying CSS attributes – even dynamic ones – right alongside HTML with JavaScript. Conceptually, that
308
+
makes it similar to [CSS-in-JS](https://reactjs.org/docs/faq-styling.html#what-is-css-in-js) – but for Kotlin.
309
+
The benefit of using a DSL is that you can use Kotlin code constructs to express formatting rules.
312
310
313
-
The template project for this tutorial already includes everything for using `kotlin-react-css`:
311
+
The template project for this tutorial already includes everything for using `kotlin-emotion`:
@@ -551,7 +550,7 @@ _state_ specific to this component.
551
550
State is one of core concepts in React. In modern React (using the so-called _Hooks API_), state is expressed
552
551
using the [`useState` hook](https://reactjs.org/docs/hooks-state.html).
553
552
554
-
1. Add the following line of code to the top of the `VideoList` declaration:
553
+
1. Add the following code to the top of the `VideoList` declaration:
555
554
556
555
```kotlin
557
556
valVideoList=FC<VideoListProps> { props ->
@@ -565,7 +564,7 @@ using the [`useState` hook](https://reactjs.org/docs/hooks-state.html).
565
564
*The `useState()` function from React instructs the framework to keep track of state across multiple invocations
566
565
of the function. For example, even though you specify a default value, React makes sure that the default value is only
567
566
assigned in the beginning. When the state changes, the component will re-render based on the new state.
568
-
*The `by` keyword indicates that `useState()` acts as a [delegated property](https://kotlinlang.org/docs/delegated-properties.html).
567
+
*The `by` keyword indicates that `useState()` acts as a [delegated property](delegated-properties.md).
569
568
Like with any other variable, you read and write values. The implementation behind `useState()` takes care of the machinery
570
569
required to make state work.
571
570
@@ -662,15 +661,14 @@ the state of a parent component, you need the state lifting again.
662
661
663
662
InReact, state always flows from parent to child. So, to change the _application_ state from one of the child components,
664
663
you need to move the logic for handling user interaction to the parent component and then pass the logic inas a prop.
665
-
Remember that inKotlin, variables can have the [type of a function](https://kotlinlang.org/docs/reference/lambdas.html#function-types).
664
+
Remember that inKotlin, variables can have the [type of a function](lambdas.md#function-types).
666
665
667
-
1. Expand the `VideoListProps` interfaceso that it contains a variable `onSelectVideo`, which is a function taking a
666
+
1. Expand the `VideoListProps` interfaceagainso that it contains a variable `onSelectVideo`, which is a function taking a
668
667
`Video` and returning `Unit`:
669
668
670
669
```kotlin
671
670
externalinterfaceVideoListProps : Props {
672
-
var videos:List<Video>
673
-
var selectedVideo:Video?
671
+
// ...
674
672
var onSelectVideo: (Video) ->Unit
675
673
}
676
674
```
@@ -757,8 +755,8 @@ to handle this in the `App` component accordingly.
757
755
}
758
756
```
759
757
760
-
The [`let` scope function](https://kotlinlang.org/docs/scope-functions.html#let), ensures that the `VideoPlayer` component
761
-
is only added when `state.currentVideo` isnotnull.
758
+
The [`let` scope function](scope-functions.md#let), ensures that the `VideoPlayer` componentis only added
759
+
when `state.currentVideo` isnotnull.
762
760
763
761
Now clicking an entry in the list will bring up the video player and populate it with the information from the clicked entry.
764
762
@@ -861,19 +859,19 @@ React has a rich ecosystem with a lot of pre-made components you can use instead
861
859
862
860
### Add the video player component
863
861
864
-
To replace the placeholder video component with an actual YouTube player, use the [react-lite-youtube-embed](https://www.npmjs.com/package/react-lite-youtube-embed)
865
-
package from npm. It can show video and control the appearance of the player.
862
+
To replace the placeholder video component with an actual YouTube player, use the `react-player` package from npm.
863
+
It can show video and control the appearance of the player.
866
864
867
-
For the component documentation and the API description, see its [README](https://www.npmjs.com/package/react-lite-youtube-embed)
865
+
For the component documentation and the API description, see its [README](https://www.npmjs.com/package/react-player)
868
866
in GitHub.
869
867
870
-
1. Check the `build.gradle(.kts)` file. The `react-lite-youtube-embed` package should be already included:
868
+
1. Check the `build.gradle(.kts)` file. The `react-player` package should be already included:
@@ -1120,8 +1120,8 @@ invoked once the `Promise` is resolved and a result is available. However, with
1120
1120
Whenever a function like `await()` is called, the method stops (suspends) its execution. It continues execution once
1121
1121
the `Promise` can be resolved.
1122
1122
1123
-
To give users a selection of videos, you can define the `fetchVideos()` function, which will fetch 25 videos from the
1124
-
same API as above. To run all the requests concurrently, use the [`async`](https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/async.html)
1123
+
To give users a selection of videos, define the `fetchVideos()` function, which will fetch 25 videos from the same API
1124
+
as above. To run all the requests concurrently, use the [`async`](https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/async.html)
1125
1125
functionality provided by Kotlin's coroutines:
1126
1126
1127
1127
1. Add the following implementation to your `App.kt`:
@@ -1136,7 +1136,7 @@ functionality provided by Kotlin's coroutines:
1136
1136
}
1137
1137
```
1138
1138
1139
-
For reasons of [structured concurrency](https://kotlinlang.org/docs/reference/coroutines/basics.html#structured-concurrency),
1139
+
For reasons of [structured concurrency](https://kotlinlang.org/docs/coroutines-basics.html#structured-concurrency),
1140
1140
the implementation is wrapped in a `coroutineScope`. You can then start 25 asynchronous tasks (one per request) and wait
0 commit comments