너의 얼굴에 느릅나무를 뿌려라

6837 단어 reactelm

Elm 세계를 떠난 지 약 1년 만에 이번 주말에 다시 시도하기로 했습니다.나는 새로운 응용 프로그램 (create-elm-app 사용) 을 만들고 실행하기 시작했다.몇 분 후에 Elm의 기쁨이 다시 돌아왔다.유용한 오류 메시지, 유형 시스템에서 데이터의 유연성을 설명합니다. - 대단합니다!
다른 하나는 내가 몇 달 동안 보조 프로젝트를 하고 있는데, 우리는 React를 사용하고 있다.비록 React는 웹 응용 프로그램을 구축하는 우수한 프레임워크이지만, 나의 손가락은 Elm를 다시 쓰기를 갈망하기 시작했다.
그리고 나서 나는 생각했다. 왜 우리는 일부 화면을 위해 Elm 모듈을 작성하고 React 구성 요소에 끼워 넣을 수 없지?
이것이 바로 본문의 주제입니다!
우선, React와 Elm 파일을 컴파일할 수 있는 webpack을 사용하는 프로젝트가 필요합니다.나는 이것을 연습으로 독자에게 남길 것이다.
이것은 Main.elm 파일의 내용입니다. 우리는 그것을 사용하여 이 문제를 해결하려고 시도할 것입니다.
module Main exposing (..)

import Browser
import Html exposing (Html, text)

main : Program () Model Msg
main =
    Browser.element
        { init = init
        , view = view
        , update = update
        , subscriptions = subscriptions
        }

type alias Model =
    {}

init : () -> ( Model, Cmd Msg )
init flags =
    ( Model
    , Cmd.none
    )

type Msg
    = Noop

update : Msg -> Model -> ( Model, Cmd Msg )
update _ model =
    ( model, Cmd.none )

view : Model -> Html Msg
view model =
    Html.div [] [text "Hello from Elm!"]

subscriptions : Model -> Sub Msg
subscriptions _ =
    Sub.none
문자열 "Hello from Elm!"만 출력하지만, React 구성 요소에서 실행할 수 있기 때문에 흥미로운 일은 없습니다.
Elm 응용 프로그램의 화면 캡처를 포장합니다.

Elm 응용 프로그램은 어떻게 초기화합니까?


SPA(단일 페이지 응용 프로그램)를 만들 때 SPA의 주 모듈을 가져와 페이지의 특정 DOM 노드에 마운트하는 입구점 Javascript가 있습니다.
이 점을 더 자세히 이해하기 위해 생성된 index.html 파일을 열 수 있습니다.
import { Elm } from '../Main';

document.addEventListener('DOMContentLoaded', () => {
  const target = document.createElement('div');
  document.body.appendChild(target);

  Elm.Main.init({ node: target });
});
hello_elm.js 새 프로젝트에서
  • 우선 Main.elm 파일
  • 에서 Elm 응용 프로그램을 가져옵니다.
  • DOMContentLoaded 이벤트에서 우리는 div에 새로운 DOM 요소를 만들고 이를 주체
  • 에 추가합니다
  • 그리고 Elm 응용 프로그램을 초기화하여 새로운 div에서 실행합니다
  • 여기서 가장 중요한 성과는 내부에서 Elm 응용 프로그램을 실행하기 위해 DOM 노드가 필요하다는 것이다.

    React 구성 요소 만들기


    현재 우리는 Elm 응용 프로그램이 어떻게 초기화되었는지 알고 있으며, React 구성 요소를 설계하여 그것을 불러오는 것을 고려할 수 있습니다.
    Elm 응용 프로그램을 초기화하는 데 유일하게 필요한 것은 DOM 노드이기 때문에 div을 보여주는 구성 요소를 만들어서 목표로 사용할 수 있습니다.
    import React from 'react';
    
    export default function ElmComponent() {
      return <div />;
    }
    
    div의 인용을 얻기 위해서, 우리는 useRefreact 갈고리를 사용하여 구성 요소의 전체 생명주기에서 DOM 노드에 대한 인용을 얻을 수 있습니다.useRef 함수는 초기 값을 사용합니다
    import React, { useRef } from 'react';
    
    export default function ElmComponent() {
      const target = useRef();
    
      return <div ref={target} />;
    }
    
    이제 응용 프로그램을 어디에 두어야 할지 알게 되었습니다. Elm 모듈을 가져오고 구성 요소가 DOM에 처음 불러올 때 useEffect 갈고리를 사용하여 초기화할 수 있습니다.
    import React, { useRef } from 'react';
    import { Elm } from '../Main';
    
    export default function ElmComponent() {
      const target = useRef();
    
      useEffect(() => Elm.Main.init({ node: target.current });
    
      return (
        <>
          <h1>Hello from React!</h1>
          <div ref={target} />
        <>
      );
    }
    
    현재 ElmComponent을 보일 때 Elm 응용 프로그램은 React 응용 프로그램에서 실행됩니다.
    최종 결과

    React에서 데이터를 어떻게 전달합니까?


    Elm 응용 프로그램을 기존 React 응용 프로그램에 끼워 넣을 때, React 응용 프로그램에서 Elm 응용 프로그램으로 데이터를 보내기를 원할 수도 있습니다.이것은 서버에 HTTP를 요청한 인증 영패에서 현재 사용자까지 모든 내용일 수 있습니다.
    이를 위해, 우리는 Elm 프로그램에서 main 함수의 형식 서명을 변경해서 프로그램이 시작할 때 초기 데이터를 받기를 희망한다는 것을 표시할 수 있습니다.그리고 프로그램에 저장할 데이터를 Model 유형에 추가해야 합니다.
    인증 영패를 React에서 Elm 프로그램으로 전달하기 위해 HTTP 요청을 할 수 있도록 모듈을 이와 같은 내용으로 변경할 수 있습니다.
    import Browser
    import Html exposing (Html, text)
    
    main : Program String Model Msg
    main =
        Browser.element
            { init = init
            , view = view
            , update = update
            , subscriptions = subscriptions
            }
    
    type alias Model =
        { authToken : String }
    
    init : String -> ( Model, Cmd Msg )
    init authToken =
        ( Model authToken
        , Cmd.none
        )
    
    type Msg
        = Noop
    
    update : Msg -> Model -> ( Model, Cmd Msg )
    update _ model =
        ( model, Cmd.none )
    
    view : Model -> Html Msg
    view model =
        Html.div [] [text <| "Token: " ++ model.authToken]
    
    subscriptions : Model -> Sub Msg
    subscriptions _ =
        Sub.none
    
    
    새로운 Elm 계획의 차이점은 다음과 같습니다.
  • ModelauthToken : String
  • 으로 구축됨
  • main의 유형 서명 현재 flags에 전달된 유형
  • 을 지정합니다
  • init은 업데이트된 형식 서명을 가지고 로고
  • 의 값을 사용하여 초기 Model을 구축합니다
    만약 우리가 지금 ElmComponent을 렌더링하고 문자열을 flags 도구로 전달한다면, Elm 프로그램은 나중에 사용할 수 있도록 초기 모델에 저장할 것입니다.새 프로그램을 실행합시다.
    import React, { useRef } from 'react';
    import { Elm } from '../Main';
    
    export default function ElmComponent() {
      const target = useRef();
    
      useEffect(() => Elm.Main.init({
        node: target.current,
        flags: "my-very-secret-token"
      });
    
      return <div ref={target} />;
    }
    
    React에서 전달하는 매개 변수가 있는 렌더링 Elm 프로그램입니다.
    또한 flags을 사용하여 더욱 복잡한 데이터를 Elm 프로그램에 전달할 수 있습니다. 예를 들어 대상, 원조, 수조 등입니다.더 많은 정보를 원하신다면, Elm 가이드에 좋은 문서가 있습니다!
    Flags · An Introduction to Elm

    어쨌든


    React 프로그램에서 이 작은 구성 블록을 사용하면 프로그램을 다시 쓸 필요가 없이 코드 라이브러리에 Elm를 도입할 수 있습니다.
    이것은 위험이 낮은 상황에서 시도하고 전체 응용 프로그램에서 그것을 확장해서 사용할 것인지를 결정하는 데 도움을 줄 수 있습니다.그렇지 않으면 Elm의 일부분만 실행할 수 있고 React로 쉽게 변환할 수 있습니다.
    그러나 Elm이 훌륭하다면 영원히 일어나지 않을 것이다.😁

    좋은 웹페이지 즐겨찾기