Feliz: v2 아이디어에 λŒ€ν•œ κ·€ν•˜μ˜ μ˜κ²¬μ€ λ¬΄μ—‡μž…λ‹ˆκΉŒ?

에 λ§Œλ“  2021λ…„ 03μ›” 17일  Β·  9μ½”λ©˜νŠΈ  Β·  좜처: Zaid-Ajaj/Feliz

μ•ˆλ…• 친ꡬ,
Feliz(및 μ‹€μ œλ‘œ Feliz.Bulma)의 일일 μ‚¬μš©μžλ‘œμ„œ μ €λŠ” 항상 prop.children μ€‘μ²©μœΌλ‘œ 인해 어렀움을 κ²ͺκ³  μžˆμŠ΅λ‹ˆλ‹€. v2 μ œμ•ˆμ— λŒ€ν•œ κ·€ν•˜μ˜ μ˜κ²¬μ„ μ•Œκ³  μ‹ΆμŠ΅λ‹ˆλ‹€.

Html.div [
    prop.className "myClass"
    Html.div "Nested"
]

μ–΄μ©Œλ©΄ 그런 일이 λΆˆκ°€λŠ₯ν•  μˆ˜λ„ μžˆμ§€λ§Œ Feliz.Engine μ—μ„œ @alfonsogarciacaro의 μž‘μ—…μ„ λ³΄μ•˜κ³  같은 μˆ˜μ€€μ˜ μ†Œν’ˆκ³Ό 어린이λ₯Ό κ°–λŠ” 것이 λ„ˆλ¬΄ 유혹적인 것 κ°™μŠ΅λ‹ˆλ‹€. πŸ˜„

discussion

κ°€μž₯ μœ μš©ν•œ λŒ“κΈ€

ν† λ‘  주제λ₯Ό λ‚˜νƒ€λ‚΄κΈ° μœ„ν•΄ 제λͺ©μ„ λ³€κ²½ν•΄ λ‹¬λΌλŠ” μ²­μ›μ„œ? πŸ˜†

@Dzoukr 이에 λŒ€ν•œ 이전 토둠이 μžˆμ—ˆμŠ΅λ‹ˆλ‹€. μ €λŠ” ν™•μ‹€νžˆ λ‹Ήμ‹  νŽΈμž…λ‹ˆλ‹€.

λ„μš°λ―Έ ν•¨μˆ˜λŠ” μ–΄μƒ‰ν•œ 이쀑 λͺ©λ‘ ꡬ문을 λ‹€μ‹œ 가져와 기본적으둜 이 lib의 μ£Όμš” 이점 쀑 ν•˜λ‚˜λ₯Ό μ œκ±°ν•˜κ³  div+class μ΄μƒμ˜ μ‹€μ œ prop μ‚¬μš©μ— 도움이 λ˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμ— 이상적이지 μ•ŠμŠ΅λ‹ˆλ‹€.

@Zaid-Ajaj 이 μ˜μ—­μ„ νƒμƒ‰ν•˜κΈ° μœ„ν•΄ λŒ€μ²΄ λ„€μž„μŠ€νŽ˜μ΄μŠ€λ₯Ό μ—΄μ–΄ μ£Όμ‹œκ² μŠ΅λ‹ˆκΉŒ? Feliz.Experimental κ°™μ€κ±°μš”? λ”°λΌμ„œ κΈ°λ³Έ Feliz λ„€μž„μŠ€νŽ˜μ΄μŠ€λŠ” React보닀 얇은 λ ˆμ΄μ–΄μ˜ λͺ©ν‘œλ₯Ό μœ μ§€ν•˜λŠ” 반면 λŒ€μ²΄λŠ” 더 독단적인 접근을 μ‹œλ„ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

μ–΄μ¨Œλ“ , λ‚˜λŠ” μ†Œν’ˆ κ·Έλ£Ήν™”λ₯Ό μœ μ§€ν•˜κΈ° μœ„ν•΄ λ‹€μŒκ³Ό 같은 것을 μ’‹μ•„ν•©λ‹ˆλ‹€.

Html.div [
    props [
        prop.className "myClass"
    ]
    Html.div "Nested"
]

props 쀑첩은 μš”μ†Œκ°€ μžˆλŠ” λ°©μ‹μœΌλ‘œ λ¬΄ν•œ 쀑첩이 μ μš©λ˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμ— prop 쀑첩이 μš”μ†Œ 쀑첩보닀 더 깔끔해 λ³΄μž…λ‹ˆλ‹€. props μ»¨ν…Œμ΄λ„ˆλŠ” Html.* μš”μ†Œμ™€ μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ³΅μœ ν•˜μ—¬ λ‘˜ λ‹€ ν¬ν•¨ν•˜λŠ” μš”μ†Œμ˜ μœ νš¨ν•œ μžμ‹μœΌλ‘œ λͺ¨λΈλ§ν•©λ‹ˆλ‹€.

μ„±λŠ₯은 μ§€μΌœλ΄μ•Ό ν•  λΆ€λΆ„μ΄μ§€λ§Œ μ‹œλ„ν•˜μ§€ μ•Šκ³ λŠ” κ·Έ 영ν–₯을 μ•Œ 수 μ—†λ‹€κ³  μƒκ°ν•©λ‹ˆλ‹€. λˆ„κ°€ μ•Œκ² μ–΄μš”. μΆ”κ°€ μž‘μ—…μ΄ λ¬΄μ„­κ²Œ 듀릴지 λͺ¨λ₯΄μ§€λ§Œ μ‹€μ œλ‘œλŠ” λ Œλ”λ§μ—μ„œ λ°œμƒν•˜λŠ” λ‹€λ₯Έ λͺ¨λ“  μž‘μ—…μ— λΉ„ν•΄ μ€‘μš”ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

λͺ¨λ“  9 λŒ“κΈ€

이런 μ’…λ₯˜μ˜ 지원을 μΆ”κ°€ν•˜λ©΄ μœ ν˜• 좔둠이 훨씬 더 κ΄€λŒ€ν•΄μ§‘λ‹ˆλ‹€(λ‚˜λŠ” μ“Έλͺ¨μ—†λ‹€κ³  말할 μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€). 그러면 Attribute = Properties = ReactElement κ°€ 있기 λ•Œλ¬Έμž…λ‹ˆλ‹€. 기본적으둜 λͺ¨λ“  것이 같은 μœ ν˜•μœΌλ‘œ λ°›μ•„λ“€μ—¬μ§ˆ κ²ƒμž…λ‹ˆλ‹€...

λ˜ν•œ 이λ₯Ό κ°€λŠ₯ν•˜κ²Œ ν•˜λ €λ©΄ 항상 μΆ”κ°€ 단계가 ν•„μš”ν•˜κΈ° λ•Œλ¬Έμ— μ„±λŠ₯에 영ν–₯을 λ―ΈμΉ  "μˆ˜λ™μœΌλ‘œ" μžμ‹μ˜ 속성을 λΆ„ν• ν•˜κΈ° μœ„ν•΄ React μœ„μ— μΆ”κ°€ λ ˆμ΄μ–΄λ₯Ό μΆ”κ°€ν•΄μ•Ό ν•©λ‹ˆλ‹€. 이것은 λ˜ν•œ 뢄리λ₯Ό λ§Œλ“œλŠ” 데 ν•„μš”ν•œ 정보λ₯Ό μ €μž₯ν•˜κΈ° μœ„ν•΄ λ²ˆλ“€ 크기λ₯Ό μ¦κ°€μ‹œν‚΅λ‹ˆλ‹€.

개인적으둜 λ‚˜λŠ” 이 κΈ°λŠ₯을 μ’‹μ•„ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

λ‚˜λŠ” 주둜 λ Œλ”λ§μ— μΆ”κ°€λ˜λŠ” λŸ°νƒ€μž„ μ˜€λ²„ν—€λ“œ λ•Œλ¬Έμ— 이 μ ‘κ·Ό 방식에 λŒ€ν•΄ μ—‡κ°ˆλ¦° 감정을 가지고 μžˆμŠ΅λ‹ˆλ‹€. λ˜ν•œ λ‚˜λŠ” 생각을 μœ μ§€ν•˜λŠ” 것을 μ„ ν˜Έ 것 ReactElement μ—μ„œ λ³„λ„μ˜ ReactAttribute . κ·Έλž˜μ„œ 개인적으둜 ν˜„μž¬ APIλ₯Ό 훨씬 더 μ„ ν˜Έν•©λ‹ˆλ‹€.

λ‚΄ κ²½ν—˜μ— λ”°λ₯΄λ©΄ μ‚¬μš©μžλ‘œλΆ€ν„° 이 λ¬Έμ œμ— λŒ€ν•΄ 많이 λ“€μ—ˆμ§€λ§Œ 클래슀 이름과 μžμ‹μ΄ μžˆλŠ” div μ»¨ν…μŠ€νŠΈμ—μ„œλ§Œ _만_μž…λ‹ˆλ‹€. λ‚΄ 일반적인 응닡은 이와 μœ μ‚¬ν•œ 것을 μž‘μ„±ν•  수 μžˆλŠ” μž‘μ€ λ„μš°λ―Έ κΈ°λŠ₯을 μž‘μ„±ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€.

div [ "myClass" ] [
  Html.div "nested"
]

μ—¬κΈ°μ—μ„œ Material UIμ—μ„œ ν–ˆλ˜ κ²ƒμ²˜λŸΌ 클래슀 λ˜λŠ” 기타 자주 μ‚¬μš©ν•˜λŠ” 속성을 μ μš©ν•˜λŠ” νš¨κ³Όμ— 더 μ ν•©ν•˜λ‹€λ©΄ κ³ μœ ν•œ ν™•μž₯ λ©”μ„œλ“œλ₯Ό μž‘μ„±ν•˜μ§€ μ•Šμ„ μ΄μœ κ°€ μ—†λŠ” 것 κ°™μŠ΅λ‹ˆλ‹€. 컴파일러λ₯Ό 더 ν˜Όλž€μŠ€λŸ½κ²Œ ν•˜κ±°λ‚˜ ν˜•μ‹ μ•ˆμ „μ„±μ„ κ°μ†Œμ‹œν‚€μ§€ μ•ŠμœΌλ©΄μ„œ F#을 μ‚¬μš©ν•˜λ©΄ ꡬ성 κ°€λŠ₯성이 μ™„μ „νžˆ μ‚¬λΌμ§‘λ‹ˆλ‹€.

[<AutoOpen>]
module MuiExtensions

open Feliz
open Feliz.MaterialUI

type Mui 
    with
    static member gridItem (children:seq<ReactElement>):ReactElement = 
        Mui.grid [
            grid.item true
            grid.children children
        ]

    static member gridItem (props:seq<IReactProperty>):ReactElement = 
        Mui.grid [
            grid.item true
            yield! props
        ]

λͺ¨λ“  μ˜κ²¬μ— κ°μ‚¬λ“œλ¦½λ‹ˆλ‹€. μ €λŠ” ν† λ‘  흐름을 μ›ν–ˆμŠ΅λ‹ˆλ‹€. πŸ‘ μ €μ—κ²Œλ„ divClassed "myClass" [ children ] μ •λ„μ˜ μ €λ§Œμ˜ λ„μš°λ―Έκ°€ μžˆμ§€λ§Œ λ‹€λ₯Έ μ‚¬λžŒμ˜ 관점을 μ•Œκ³  μ‹Άμ—ˆμŠ΅λ‹ˆλ‹€.

이것은 React μš”μ†Œλ₯Ό λͺ©λ‘μ—μ„œ 계산 ν‘œν˜„μ‹μœΌλ‘œ λ³€κ²½ν•œ 경우 μœ ν˜• μ œν•œμ„ μœ μ§€ν•˜λ©΄μ„œ μ‹€μ œλ‘œ κ°€λŠ₯ν•΄μ•Ό ν•©λ‹ˆλ‹€.

div {
    className "myClass"

    div { ... }
}

CE κ΅¬ν˜„μ€ μ½”λ“œλ² μ΄μŠ€μ˜ 크기λ₯Ό 늘리고 μœ μ§€ 관리λ₯Ό 더 μ–΄λ ΅κ²Œ λ§Œλ“€λ©° propsκ°€ μ •μ˜λ  β€‹β€‹λ•Œ κΈ°λ³Έ μš”μ†Œμ™€ 같은 일뢀λ₯Ό μ²˜λ¦¬ν•˜λŠ” 것은 μ•½κ°„ κΉŒλ‹€λ‘­μŠ΅λ‹ˆλ‹€/μ§€κΈˆμ²˜λŸΌ 개발 쀑이 μ•„λ‹ˆλΌ 컴파일 μ‹œ μ‹€νŒ¨ν•΄μ•Ό ν•©λ‹ˆλ‹€.

// Would probably need to make the base builder generic so we can use a type restriction and define this DU for
// each element so we can properly restrict what types are valid as primatives
type ReactBuilderChild =
    | Child of ReactElement
    | Children of ReactElement list
    | Float of float
    | Int of int
    | String of string
    | None

    member this.GetChildren () =
        match this with
        | ReactBuilderChild.Children children -> children
        | _ -> failwith "Cannot combine children with primitive values."

type ReactBuilderState =
    { Children: ReactElement list
      Props: IReactProperty list } 

[<AbstractClass;NoEquality;NoComparison>]
type ReactBuilder () =
    [<EditorBrowsable(EditorBrowsableState.Never)>]
    member _.Yield (x: ReactElement) = { Children = ReactBuilderChild.Child x; Props = [] }
    [<EditorBrowsable(EditorBrowsableState.Never)>]
    member _.Yield (x: ReactElement list) = { Children = ReactBuilderChild.Children x; Props = [] }
    [<EditorBrowsable(EditorBrowsableState.Never)>]
    member _.Yield (x: float) = { Children = ReactBuilderChild.Float x; Props = [] }
    ...
    [<EditorBrowsable(EditorBrowsableState.Never)>]
    member _.Yield (x: unit) = { Children = ReactBuilderChild.None; Props = [] }

    [<EditorBrowsable(EditorBrowsableState.Never)>]
    member _.Combine (state: ReactBuilderState, x: ReactBuilderState) = 
        { Children = (state.Children.GetChildren()) @ (x.Children.GetChildren()); Props = state.Props @ x.Props }

    [<EditorBrowsable(EditorBrowsableState.Never)>]
    member _.Zero () = { Children = ReactBuilderChild.None; Props = [] }

    [<EditorBrowsable(EditorBrowsableState.Never)>]
    member this.For (state: ReactBuilderState, f: unit -> ReactBuilderState) = this.Combine(state, f())

    [<CustomOperation("className")>]
    member _.className (state: ReactBuilderState, value: string) =
        { state with Props = (Interop.mkAttr "className" value)::state.Props }

    [<CustomOperation("children")>]
    member _.children (state: ReactBuilderState, value: ReactElement list) =
        { state with Children = state.Children @ value }

    abstract Run : ReactBuilderState -> ReactElement

[<NoEquality;NoComparison>]
type DivBuilder () =
    inherit ReactBuilder()

    [<EditorBrowsable(EditorBrowsableState.Never)>]
    member _.Run (state: ReactBuilderState) = 
        match state with
        | { Children = ReactBuilderChild.None; Props = props } -> Interop.createElement "div" props
        | { Children = ReactBuilderChild.Children children } -> Interop.reactElementWithChildren "div" children
        | { Children = ReactBuilderChild.Float f } -> Interop.reactElementWithChild "div" f
        | _ -> ...

let div = DivBuilder()

λ‚΄κ°€ ν™•μ‹ ν•  수 μ—†λŠ” 것은 Fable이 CE λ°°κ΄€μ˜ 일뢀/전체λ₯Ό μ˜¬λ°”λ₯΄κ²Œ μ»΄νŒŒμΌν•˜κ³  μž‘μ—…μ„ 검색 κ°€λŠ₯ν•˜κ²Œ λ§Œλ“œλŠ” λ°©λ²•μž…λ‹ˆλ‹€(ν˜„μž¬ prop μœ ν˜•μΈ κ²ƒμ²˜λŸΌ).

ν† λ‘  주제λ₯Ό λ‚˜νƒ€λ‚΄κΈ° μœ„ν•΄ 제λͺ©μ„ λ³€κ²½ν•΄ λ‹¬λΌλŠ” μ²­μ›μ„œ? πŸ˜†

@Dzoukr 이에 λŒ€ν•œ 이전 토둠이 μžˆμ—ˆμŠ΅λ‹ˆλ‹€. μ €λŠ” ν™•μ‹€νžˆ λ‹Ήμ‹  νŽΈμž…λ‹ˆλ‹€.

λ„μš°λ―Έ ν•¨μˆ˜λŠ” μ–΄μƒ‰ν•œ 이쀑 λͺ©λ‘ ꡬ문을 λ‹€μ‹œ 가져와 기본적으둜 이 lib의 μ£Όμš” 이점 쀑 ν•˜λ‚˜λ₯Ό μ œκ±°ν•˜κ³  div+class μ΄μƒμ˜ μ‹€μ œ prop μ‚¬μš©μ— 도움이 λ˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμ— 이상적이지 μ•ŠμŠ΅λ‹ˆλ‹€.

@Zaid-Ajaj 이 μ˜μ—­μ„ νƒμƒ‰ν•˜κΈ° μœ„ν•΄ λŒ€μ²΄ λ„€μž„μŠ€νŽ˜μ΄μŠ€λ₯Ό μ—΄μ–΄ μ£Όμ‹œκ² μŠ΅λ‹ˆκΉŒ? Feliz.Experimental κ°™μ€κ±°μš”? λ”°λΌμ„œ κΈ°λ³Έ Feliz λ„€μž„μŠ€νŽ˜μ΄μŠ€λŠ” React보닀 얇은 λ ˆμ΄μ–΄μ˜ λͺ©ν‘œλ₯Ό μœ μ§€ν•˜λŠ” 반면 λŒ€μ²΄λŠ” 더 독단적인 접근을 μ‹œλ„ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

μ–΄μ¨Œλ“ , λ‚˜λŠ” μ†Œν’ˆ κ·Έλ£Ήν™”λ₯Ό μœ μ§€ν•˜κΈ° μœ„ν•΄ λ‹€μŒκ³Ό 같은 것을 μ’‹μ•„ν•©λ‹ˆλ‹€.

Html.div [
    props [
        prop.className "myClass"
    ]
    Html.div "Nested"
]

props 쀑첩은 μš”μ†Œκ°€ μžˆλŠ” λ°©μ‹μœΌλ‘œ λ¬΄ν•œ 쀑첩이 μ μš©λ˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμ— prop 쀑첩이 μš”μ†Œ 쀑첩보닀 더 깔끔해 λ³΄μž…λ‹ˆλ‹€. props μ»¨ν…Œμ΄λ„ˆλŠ” Html.* μš”μ†Œμ™€ μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ³΅μœ ν•˜μ—¬ λ‘˜ λ‹€ ν¬ν•¨ν•˜λŠ” μš”μ†Œμ˜ μœ νš¨ν•œ μžμ‹μœΌλ‘œ λͺ¨λΈλ§ν•©λ‹ˆλ‹€.

μ„±λŠ₯은 μ§€μΌœλ΄μ•Ό ν•  λΆ€λΆ„μ΄μ§€λ§Œ μ‹œλ„ν•˜μ§€ μ•Šκ³ λŠ” κ·Έ 영ν–₯을 μ•Œ 수 μ—†λ‹€κ³  μƒκ°ν•©λ‹ˆλ‹€. λˆ„κ°€ μ•Œκ² μ–΄μš”. μΆ”κ°€ μž‘μ—…μ΄ λ¬΄μ„­κ²Œ 듀릴지 λͺ¨λ₯΄μ§€λ§Œ μ‹€μ œλ‘œλŠ” λ Œλ”λ§μ—μ„œ λ°œμƒν•˜λŠ” λ‹€λ₯Έ λͺ¨λ“  μž‘μ—…μ— λΉ„ν•΄ μ€‘μš”ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

@zanaptak λ§μ”€ν•˜μ‹  λŒ€λ‘œ μ†Œν’ˆλ“€μ΄ μ•„μ΄λ“€μ²˜λŸΌ 깊게 μžˆμ–΄μ„œ μ €λŠ” κ·Έ 아이디어가 μ•„μ£Ό μ’‹μŠ΅λ‹ˆλ‹€.


λ„μš°λ―Έ 및 이쀑 λͺ©λ‘ ꡬ문 주제

div+class보닀 훨씬 더 λ§Žμ€ μ‹€μ œ μ†Œν’ˆ μ‚¬μš©μ— 도움이 λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

let inline withProps elementFunction props (children: #seq<ReactElement>) =
    (prop.children (children :> ReactElement seq))
    :: props
    |> elementFunction

let myDiv = withProps Html.div

myDiv [ prop.className "myClass" ] [
    Html.div "Nested"
]

μ›ν•˜λŠ” 경우 λͺ¨λ“  μš”μ†Œμ— "이쀑 λͺ©λ‘"κ³Ό 같은 ꡬ문을 μ‚¬μš©ν•˜λ„λ‘ μ—°μ‚°μžλ₯Ό μ •μ˜ν•  μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€.

let inline (@+) elementFunction props =
    fun children -> withProps elementFunction props children

let inline (@++) elementFunction prop =
    fun children -> withProps elementFunction [ prop ] children

Html.div @+ [ prop.className "myClass" ]
<| [ Html.div "nested" ]

Html.div @++ prop.className "myClass"
<| [ Html.div "nested" ]

"더 μ’‹μ•„ λ³΄μ΄λŠ”" 것이 주관적일 수 있기 λ•Œλ¬Έμ— 이것은 κΉŒλ‹€λ‘œμš΄ μ£Όμ œμž…λ‹ˆλ‹€. μ•„λ§ˆλ„ κ°€μž₯ μ€‘μš”ν•œ 것은 μ£Όμš” λ³€κ²½ 사항을 ν”Όν•˜λŠ” κ²ƒμ΄μ§€λ§Œ, μ‹€ν—˜μ„ ν•˜κ³  μ‹Άλ‹€λ©΄ Feliz.Engine 을 μ‚¬μš©ν•˜λ©΄ λ©λ‹ˆλ‹€.

// Dependencies:
// - Fable.React
// - Feliz.Engine.Event dependencies

open Fable.Core
open Fable.Core.JsInterop
open Feliz
open Fable.React

type Node =
    | El of ReactElement
    | Style of string * string
    | Prop of string * obj
    member this.AsReactEl =
        match this with
        | El el -> el
        | _ -> failwith "not an element"

let private makeNode tag nodes =
    let props = obj()
    let style = obj()
    let children = ResizeArray()
    nodes |> Seq.iter (function
        | El el -> children.Add(el)
        | Style(k, v) -> style?(k) <- v
        | Prop(k, v) -> props?(k) <- v
    )
    if JS.Constructors.Object.keys(style).Count > 0 then
        props?style <- style
    ReactBindings.React.createElement(tag, props, children) |> El

let Html = HtmlEngine(makeNode, str >> El, fun () -> El nothing)

let Svg = SvgEngine(makeNode, str >> El, fun () -> El nothing)

let prop = AttrEngine((fun k v -> Prop(k, v)), (fun k v -> Prop(k, v)))

let style = CssEngine(fun k v -> Style(k, v))

let ev = EventEngine(fun k f -> Prop("on" + k.[0].ToString().ToUpper() + k.[1..], f))

ν…ŒμŠ€νŠΈ:

let myEl = // Node
    Html.div [
        prop.className "myClass"
        Html.div "Nested"
    ]

let myElAsReactEl = myEl.AsReactEl // ReactElement 

λ„μš°λ―Έ ν•¨μˆ˜λŠ” μ–΄μƒ‰ν•œ 이쀑 λͺ©λ‘ ꡬ문을 λ‹€μ‹œ κ°€μ Έμ˜€κΈ° λ•Œλ¬Έμ— 이상적이지 μ•ŠμŠ΅λ‹ˆλ‹€.

@zanaptak λ„μš°λ―Έ ν•¨μˆ˜λŠ” 두 개의 λͺ©λ‘μ„ μž…λ ₯으둜 μ‚¬μš©ν•  ν•„μš”κ°€ μ—†μŠ΅λ‹ˆλ‹€. div [ "class" ] [ ] λŠ” 두 개의 λͺ©λ‘μ„ κ°€μ Έμ˜€λŠ” 일반적인 μ‹œλ‚˜λ¦¬μ˜€μ˜ ν•œ 예일 λΏμž…λ‹ˆλ‹€. μ΄λŸ¬ν•œ κΈ°λŠ₯은 보기λ₯Ό 더 λ‹¨μˆœν•˜κ²Œ λ§Œλ“œλŠ” ꡬ성 μš”μ†ŒμΌ μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€.

Todo.List [ for item in items -> Todo.Item item ]

기술적으둜 λͺ©λ‘μ„ λ¬΄ν•œλŒ€λ‘œ 쀑첩할 수 μžˆμ§€λ§Œ 그것은 아이디어가 μ•„λ‹™λ‹ˆλ‹€. 더 큰 UI μ½”λ“œμ—μ„œ 더 μž‘μ€ κΈ°λŠ₯μ΄λ‚˜ ꡬ성 μš”μ†Œλ₯Ό μ‚¬μš©ν•˜λ©΄ κ· ν˜•μ΄ μœ μ§€λ©λ‹ˆλ‹€.

κ·ΈλŸ¬λ‚˜ μ΄μƒμ μœΌλ‘œλŠ” μ½”λ“œλ₯Ό 자주 λΆ„ν•΄ν•  ν•„μš”κ°€ μ—†μœΌλ©° ν•˜λ‚˜μ˜ κΈ°λŠ₯은 κ°€λŠ₯ν•œ ν•œ 읽기 μ‰¬μ›Œμ•Ό ν•©λ‹ˆλ‹€. μ •λ¦¬ν•˜λŠ” 생각이 λ•Œλ•Œλ‘œ _flow_λ₯Ό μ—†μ• κΈ° λ•Œλ¬Έμž…λ‹ˆλ‹€. 이것은 Fable.React의 DSL의 λ¬Έμ œμ˜€μŠ΅λ‹ˆλ‹€. μ—¬κΈ°μ„œ 맀번 ν˜•μ‹μ„ μ§€μ •ν•˜λŠ” 방법에 λŒ€ν•΄ _생각_ν•΄μ•Ό ν–ˆμŠ΅λ‹ˆλ‹€. FelizλŠ” children 의 두 μˆ˜μ€€ 쀑첩을 ν¬μƒν•˜μ—¬ 이 문제λ₯Ό μˆ˜μ •ν•©λ‹ˆλ‹€.

μ†”μ§νžˆ μ€μ΄μ•Œμ΄ 뭔지 잘 λͺ¨λ₯΄κ² μŠ΅λ‹ˆλ‹€. @alfonsogarciacaroκ°€ λ§ν–ˆλ“―μ΄

"더 μ’‹μ•„ λ³΄μ΄λŠ”" 것이 주관적일 수 있기 λ•Œλ¬Έμ— 이것은 κΉŒλ‹€λ‘œμš΄ μ£Όμ œμž…λ‹ˆλ‹€.

μ‹€ν—˜ 주제:

이 μ˜μ—­μ„ νƒμƒ‰ν•˜κΈ° μœ„ν•΄ λŒ€μ²΄ λ„€μž„μŠ€νŽ˜μ΄μŠ€λ₯Ό μ—΄μ–΄ μ£Όμ‹œκ² μŠ΅λ‹ˆκΉŒ? Feliz.Experimental κ°™μ€κ±°μš”? λ”°λΌμ„œ κΈ°λ³Έ Feliz λ„€μž„μŠ€νŽ˜μ΄μŠ€λŠ” React보닀 얇은 λ ˆμ΄μ–΄μ˜ λͺ©ν‘œλ₯Ό μœ μ§€ν•˜λŠ” 반면 λŒ€μ²΄λŠ” 더 독단적인 접근을 μ‹œλ„ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

ν˜„μž¬λ‘œμ„œλŠ” Feliz ν”„λ‘œμ νŠΈμ—μ„œ λ‹€λ₯Έ DSL을 μœ μ§€ν•  κ³„νšμ΄ μ—†μŠ΅λ‹ˆλ‹€. μ €λŠ” OSS μ‹œκ°„/μš©λŸ‰μ΄ 맀우 μ œν•œλ˜μ–΄ 있으며 λ¬Έμ„œ, μƒ˜ν”Œ 및 더 잘 ν…ŒμŠ€νŠΈλœ μƒνƒœκ³„ λΌμ΄λΈŒλŸ¬λ¦¬μ™€ 같은 ν˜„μž¬ μ ‘κ·Ό 방식을 κ°œμ„ ν•˜κΈ° μœ„ν•œ λ…Έλ ₯을 기울이고 μ‹ΆμŠ΅λ‹ˆλ‹€.

즉, @alfonsogarciacaro의 Feliz.Engine을 자유둭게 μ‹€ν—˜ν•˜κ³  μžμ‹ μ—κ²Œ 더 μ ν•©ν•œ DSL을 μ‚¬μš©ν•˜μ‹­μ‹œμ˜€.

이 νŽ˜μ΄μ§€κ°€ 도움이 λ˜μ—ˆλ‚˜μš”?
0 / 5 - 0 λ“±κΈ‰