Skip to content

Kotlin/JS를 이용하여 Kotlin으로 React 프로그래밍하기!

License

Notifications You must be signed in to change notification settings

technical-learn-room/kotlin-react-learn

Repository files navigation

코틀린으로 리액트 프로그래밍하기!

kotlin react image

코틀린으로 리액트 프로그래밍을 하시기 전에
수신 객체 지정 람다프로퍼티 위임(by)에 대해서 미리 선행하시는 걸 추천드립니다.

컴포넌트 생성하기

@JsExport
class TestComponent : RComponent<RProps, RState>() {
    override fun RBuilder.render() {
        div {
            a {
                +"Hello, world!"
            }
        }
    }
}

컴포넌트를 생성하기 위해서는 RComponent를 상속받는 클래스를 만들면 됩니다.
그리고 RBuilder.render() 확장 함수를 오버라이딩하고
HTML Kotlin DSL을 이용하여 마음껏 코드를 작성하시면 됩니다.

컴포넌트 조립하기

@JsExport
class TestComponent : RComponent<RProps, RState>() {
    override fun RBuilder.render() {
        div {
            aComponent {}
        }
    }
}

@JsExport
class AComponent : RComponent<RProps, RState>() {
    override fun RBuilder.render() {
        a {
            +"My name is jaychy-yy!"
        }
    }
}

fun RBuilder.aComponent(handler: RProps.() -> Unit): ReactElement {
    return child(AComponent::class) {
        this.attrs(handler)
    }
}

리액트를 제대로 사용하기 위해서는 한 컴포넌트에서 다른 컴포넌트를 가져와 조립할 수 있어야합니다.
RBuilder.render()는 수신 객체 지정 람다로 구현되어 있기 때문에
RBuilder.aComponent()처럼 RBuilder의 함수로 확장해야 합니다.

만약 이후에 소개할 props가 필요없을 경우 다음과 같이 handler를 제거하여도 무방합니다.

fun RBuilder.aComponent(): ReactElement {
    return child(AComponent::class) {}
}

props 사용하기

external interface AComponentProps : RProps {
    var name: String
}

@JsExport
class AComponent : RComponent<AComponentProps, RState>() {
    override fun RBuilder.render() {
        a {
            +"My name is ${props.name}!"
        }
    }
}

fun RBuilder.aComponent(handler: AComponentProps.() -> Unit): ReactElement {
    return child(AComponent::class) {
        this.attrs(handler)
    }
}

props를 사용하기 위해서는 RProps를 상속 받는 external interface를 생성하면 됩니다.
내부 프로퍼티는 임의로 라이브러리에서 생성 후 초기화 되기 때문에
반드시 var로 선언해야 합니다.

이제 AComponent를 사용하는 측에서는 attrs {}을 통해 props를 전달할 수 있습니다.

@JsExport
class TestComponent : RComponent<RProps, RState>() {
    override fun RBuilder.render() {
        div {
            aComponent {
                attrs {
                    name = "jaychy-yy"
                }
                // attrs.name = "jaychy-yy" // 이렇게도 할 수 있습니다.
            }
        }
    }
}

컴포넌트의 상태 저장하기

data class AComponentState(
    val test: String,
) : RState

@JsExport
class AComponent : RComponent<AComponentProps, AComponentState>() {

    init {
        state = AComponentState("")
    }

    override fun RBuilder.render() {
        a {
            +"My name is ${props.name}!"
        }
    }
}

컴포넌트의 상태를 저장하기 위해서는 저장할 공간을 data class로 표현합니다.
사용할 땐 state.test 형식으로 사용하고
상태를 변경하기 위해서는 setState() 메소드를 사용합니다.
또한 초기상태를 init block에서 진행할 수 있습니다.

CSS 적용하기

object MyStyles : StyleSheet("MyStyles", isStatic = true) {
    val name by css {
        fontSize = 20.px
        color = rgb(0, 0, 0)
        backgroundColor = Color.white
    }
}

스타일시트를 만드는 방법은 위와 같습니다.
생긴 것은 styled-component와 비슷해서 쉽게 사용할 수 있을 것 같습니다.
또한 보통 object로 선언하여 싱글톤으로 만들어 효율적으로 사용하게 합니다.

@JsExport
class AComponent : RComponent<AComponentProps, AComponentState>() {
    init {...}
    override fun RBuilder.render() {
        styledA {
            css {
                +MyStyles.name
            }
            +"My name is ${props.name}!"
        }
    }
}

스타일을 적용하기 위해서는 태그를 styled... 태그로 변경하여야 합니다.
styled... 태그 안에는 css() 함수를 사용할 수 있도록 CSSBuilder가 생성됩니다.

+로 연결되는 것은 내부적으로 연산자 오버로딩이 되어 있기 때문입니다.

Library & Framework

  • kotlin/js - 1.5.10
  • kotlin react - 17.0.1-pre.148-kotlin-1.4.30
  • kotlin react dom - 17.0.1-pre.148-kotlin-1.4.30
  • kotlin styled - 5.2.1-pre.148-kotlin-1.4.30

ToDoList Structure

src
  ㄴ main
      ㄴ kotlin
          ㄴ MainStyles.kt        ] - Styled Component 형식으로 정리한 스타일 객체
          ㄴ ToDoListStyles.kt    ]
          ㄴ client.kt            - 이후에 나오는 컴포넌트들을 root 아래에 두기 위한 기초 컴포넌트
          ㄴ main.kt              - ToDoList의 메인 화면 컴포넌트
          ㄴ toDo.kt              - ToDoList 내부의 ToDo를 담당하는 컴포넌트
          ㄴ toDoInsertion.kt     - ToDo를 생성하기 위한 input 컴포넌트
          ㄴ toDoList.kt          - ToDoList의 몸체 
      ㄴ resources
          ㄴ index.html           - 빌드 후 생성된 kotlin-react.learn.js 스크립트를 실행할 기초 HTML

About

Kotlin/JS를 이용하여 Kotlin으로 React 프로그래밍하기!

Topics

Resources

License

Stars

Watchers

Forks