Haxe 및 React

13399 단어 HaxeReact
Haxe에서 JavaScript를 출력하는 것은 정적 유형의 언어를 좋아하고 JavaScript를 별로 좋아하지 않지만 웹 콘텐츠를 만들고 싶은 사람에게는 좋은 선택이라고 생각합니다.
그럼에도 불구하고 Haxe는 Type Script처럼 Java Script에 접근하지 않는다. Haxe와 Java Script 라이브러리의 호환성은 매우 고민스러운 문제이다.jQuery를 사용하면 Haxe를 사용하는 맛을 줄일 수 있습니다. 변수명은 '$' 를 사용할 수 없기 때문에 AnglarJS를 사용할 수 없습니다.
고민의 결과는 다이나믹형과 untyped 키워드를 사용해 동적 언어로 프로그램 라이브러리를 쓸지, 아니면 JS로 만든 프로그램 라이브러리getElementById 손으로 쓰는 것을 포기하고 노력할지 이런 선택을 강요당했다.
그럼 지금 유행하는 리액션은 어때요?
실제로 사용한 소감이 최고예요.
Haxe부터 쉽게 사용할 수 있는 자바스크립트의 프로그램 라이브러리가 이렇게 많아서 나는 상당히 놀랐다.

haxe-react 사용


Haxe에서 JavaScript까지의 프로그램 라이브러리를 사용할 때, 프로그램 라이브러리의 js 파일과 함께 extern이라는 형식 정의 파일을 사용합니다.
리액트의 경우 이미 haxe-react 항목이 있기 때문에 이쪽 항목을 사용합니다.
haxelib install react
를 설치하고 컴파일 옵션에 추가-lib react합니다.
이렇게 되면 다음과 같은 React를 사용할 수 있습니다.
import api.react.ReactComponent;
import api.react.React;
import js.Browser;
import api.react.ReactDOM;

class App extends ReactComponent {

    static public function main() {
        ReactDOM.render(React.createElement(App), Browser.document.getElementById('app'));
    }

    public function new() {
        super();
    }

    override function render() {
        var cname = 'foo';
        return React.createElement('div', {className:cname}, [/*children*/]);
    }
}

JSX도 움직여요.


haxe-react가 주목할 만한 곳은 여기다.React.JSX는 가상 DOM 트리를 나타내는 DSL을 제공하고haxe-react도 jsx 함수를 사용하여 JSX의 문법을 사용하여 가상 DOM을 기술할 수 있다.
import api.react.ReactComponent;
import api.react.ReactDOM;
import js.Browser;
import api.react.ReactMacro.jsx;

class App extends ReactComponent {
    static public function main() {
        ReactDOM.render(jsx('<App/>'), Browser.document.getElementById('app'));
    }

    public function new() {
        super();
    }

    override function render() {
        var cname = 'foo';
        var children = '';
        return jsx('<div className=$cname>${children}</div>');
    }
}
jsx의 함수는 매크로로 실현됩니다.즉, Haxe의 컴파일링과 동시에 JSX를 컴파일하여 최초의 샘플 코드와 같은 JavaScript의 코드를 출력하는 것이다.
haxe-react에는 원래 React의 JSX 컴파일러와 다른 JSX 컴파일러가 설치되어 있습니다.
위 코드를 자세히 살펴보면 기존 JSX{}에 변수를 쓰는 문법과 달리 $부터의Haxe 문자열 내 변수의 기재법을 사용한다.이것은 Haxe의 원래 문법과 비슷한 문법으로 IDE상$ 이후 Haxe의 변수 보충회가 더욱 효과적이다.물론 {}로도 쓸 수 있습니다.

기타 기술 방법


JSX로 기술할 수 있다고 썼지만, 개인적으로는 JSX로 쓰는 방법을 별로 좋아하지 않는다.XML의 기술이 보완 효과가 별로 없다는 이유에서다.수정하지 않고 XML을 쓰는 것은 매우 번거롭고, 자신이 쓴 구성 요소도 매우 번거롭다.
예를 들어 레벨 경로foo.bar.Form의 ReactComponent를 만드는 경우
jsx('<foo.bar.Form />');
이렇게 전체 경로를 기술하거나 미리 기술import foo.bar.Form합니다.둘 다 IDE의 자동 import 기능과 맞지 않는다.
Haxe 사용의 장점 중 하나는 강력한 IDE 지원이지만, JSX를 사용하면 그 혜택을 받을 수 없다.
말은 그렇지만 처음에 그 예의 작법도 매우 복잡하니 다음에 다른 기술 방법을 소개하겠습니다.

using api.react.React


다음 기술 방법인 IDE의 보완도 쓰기 좋은 느낌을 준다.
import api.react.ReactComponent;
import api.react.ReactDOM;
import js.Browser;
using api.react.React; // importではなくusingなのがポイント

class App extends ReactComponent {

    static public function main() {
        ReactDOM.render(App.createElement(), Browser.document.getElementById('app'));
    }

    public function new() {
        super();
    }

    override function render() {
        var cname = 'foo';
        return 'div'.createElement({className:cname}, [/*children*/]);
    }
}
using는 정적 확장이라고 불리는 기능입니다.이렇게 하면 api.react.React의 함수static를 첫 번째 매개 변수 형식의 확장에 사용할 수 있다.

파일 트리 설치


저는 Haxe 스타일의 샘플 코드를 실현해 보고 싶습니다.무슨 말을 하려면 파일 트리 설치야.
폴더를 열거나 닫으려면 누르십시오.

아이콘은 Fugue Icons(CCBY3.0)을 사용했습니다.
실제 인코딩은 이런 느낌입니다.
import api.react.ReactComponent;
import api.react.ReactDOM;
import js.Browser;
using api.react.React;

class Sample {
    // エントリーポイントになるメイン関数。
    public static function main() {

        // ファイルツリーの構造体を作成
        var tree = FileTree.Folder(
            "トップ",
            true, // 開
            [
                Folder(
                    "デスクトップ",
                    true, // 開
                    [
                        File("メモ.txt"),
                        Folder(
                            "大事なもの",
                            true, // 開
                            [
                                File("写真1.png"),
                                File("写真2.png"),
                            ]
                        )
                    ]
                ),
                Folder(
                    "ミュージック",
                    false, // 閉
                    [
                        File("洋楽.mp3"),
                        File("チップチューン.mp3"),
                    ]
                )
            ]
        );

        // ファイルツリーの表示の開始
        ReactDOM.render(
            FileComponent.createElement({tree: tree}),
            Browser.document.getElementById('app')
        );
    }
}

// パラメータ付きのEnumとしてファイルのツリー構造の型を定義
enum FileTree
{
    File(name:String);
    Folder(name:String, open:Bool, children:Array<FileTree>);
}

// ファイルの状態の型定義
typedef FileProps =
{
    tree: FileTree,
}

// フォルダの型定義
typedef FolderProps =
{
    ?name:String,
    ?open:Bool,
    ?children:Array<FileTree>,
}

// ファイル要素。Propsの型を、型パラメータで指定
class FileComponent extends ReactComponentOfProps<FileProps>
{
    public function new (props:FileProps)
    {
        super();
    }

    public override function render():ReactComponent {
        // switchした結果を返す
        return switch (state.tree)
        {
            // ファイルのときは単なるdiv要素
            case File(name):
                'div'.createElement(
                    {className: "file"},
                    name
                );

            // フォルダのときはFolderComponent
            case Folder(name, open, children):
                FolderComponent.createElement({
                    open: open,
                    name: name,
                    children: children,
                });
        }
    }
}

// フォルダ要素。PropsとStateの型を、型パラメータで指定
class FolderComponent extends ReactComponentOfPropsAndState<FolderProps, FolderProps>
{
    public function new (props:FolderProps)
    {
        super();
        // propsをそのままstateとして使用
        state = props;
    }

    public function onClick():Void
    {
        // クリックされたら開閉を切り替え
        setState({ open: !state.open });
    }

    public override function render():ReactComponent {
        var label = 'div'.createElement(
            {
                // ファイルが開いてる場合と、閉じてる場合でアイコンを変える。
                className: if (state.open) 'opened-folder' else 'closed-folder',

                // クリックされたときのハンドラ
                onClick: onClick,
            },
            state.name
        );

        return 'div'.createElement(
            {},
            if (state.open) {
                [
                    label,
                    // 開いている場合、子を表示
                    'div'.createElement(
                        {
                            className: 'children',
                        },
                        [
                            // 配列内包表記で、子要素の配列を初期化
                            for (tree in state.children) {
                                FileComponent.createElement({ tree: tree });
                            }
                        ]
                    )
                ];
            } else {
                label;
                // 閉じてる場合、子は表示しない。
            }
        );
    }
}
파일 트리의 데이터 구조를 매개변수가 있는 Enum으로 표시한 다음 React로 직접 그릴 수 있습니다.

총결산


해xe의 강력한 정적형태, IDE의 지원, 강력한 매크로 등 장점은 리액트를 사용해도 피해가 없어 충분히 활용할 수 있다.매개변수가 있는 Enum은 상태를 표현하는 데이터 구조로서 매우 강하다는 점도 상성이 좋은 점이다.
따라서 파일 트리와 같은 jQuery 등 실현하기 어려운 구성 요소도 간단한 코드로 실현할 수 있다.
React는 AltJS의 기능을 방해하지 않는다. Haxe뿐만 아니라 다른 AltJS 사용자들도 이런 소리를 낸다.
React 및 함수형 AltJS

Flex 정보


다만, Flex를 구현하는 방법에는 문제가 있습니다.
JavaScript의 프로그램 라이브러리에서 extern을 특별히 제작하지 않은 것 같습니다. JavaScript의 프로그램 라이브러리를 사용하면 Haxe와의 호환성에 문제가 될 수 있습니다.
디스패치에 보내고 싶은 이븐트 등 강요형 물건이 많기 때문에 해시 자체로 시행하는 것이 현명하다.
haxe-react의 샘플 코드의 TODO 응용에서는 msignal처럼 매우 간단한 스케줄러의 프로그램 라이브러리만 사용하여 Flex허가 설치를 하기 때문에 참고할 수 있습니다.

좋은 웹페이지 즐겨찾기