👽

Rust | Dioxus で始める TODO アプリ開発

2024/09/30に公開

はじめに

本記事では Rust の Dioxus というライブラリを使って、webフロントエンドの開発を行っていきます。
以前、Yew というライブラリを使って、似たような記事を執筆しましたが、今回は新たに Dioxus というライブラリを発見したため、使いながら記事を書いていこうと思います!

https://dioxuslabs.com/

Dioxus のセットアップ

まずは、Dioxus CLI をインストールしていきます。

cargo install dioxus-cli

インストールが終わると、dxコマンドが実行できるようになりますので、
以下コマンドを実行し、プロジェクトディレクトリを作成していきます。

dx new

コマンドを実行すると、いくつかのセクションに回答を求められるため、適した回答を行っていきます。

  • Which sub-template should be expanded?
    • Web
  • Project Name
    • dioxus-web
  • How do you want to create CSS?
    • Tailwind
  • Should the application use the Dioxus router?
    • true

私は今回、WebAssembly を介したクライアントサイドでのレンダリングを試したいため Webを選択しました。
Tailwind はなじみがあるのと、Dioxus Router に関しては完全に興味ですw

WebAssembly にコンパイルし、サンプルを起動する

これでプロジェクトディレクトリが作成されましたので、試しに起動していきます!

cd dioxus-web
dx serve

http://localhost:8080にアクセスすると、以下のようなカウンターアプリが表示されました。

http://localhost:8008

プロジェクトディレクトリ直下のtargetフォルダを見てみると、
wasm32-unknown-nbknownが生成され、WebAssemblyとしてビルドされていることが分かりました!

Dioxus hooks を活用し、TODOアプリを作ってみました

Dioxus には Dioxus hooks なるものが存在し、Webアプリ開発をシームレスに行うことができます。
React などのフレームワークのような使い勝手ができそうでした✨

作成したコードはこのような感じです。

main.rs
#![allow(non_snake_case)]

use dioxus::prelude::*;
use dioxus_logger::tracing::{info, Level};

#[derive(Clone, Routable, Debug, PartialEq)]
enum Route {
    #[route("/")]
    Home {},
}

fn main() {
    dioxus_logger::init(Level::INFO).expect("failed to init logger");
    info!("starting app");
    launch(App);
}

fn App() -> Element {
    rsx! {
        Router::<Route> {}
    }
}

#[component]
fn Home() -> Element {
    let mut new_todo = use_signal(String::new);
    let mut todos: Signal<Vec<String>> = use_signal(|| vec!["買い物をする".to_string()]);

    let add_todo = move |_| {
        if !new_todo.read().is_empty() {
            todos.write().push(new_todo.read().clone());
            new_todo.set("".to_string());
        }
    };

    rsx! {
        div {
            h1 { "Todo App" }
            ul {
                {todos.read().iter().map(|todo| rsx!(
                    li {
                        span {
                            "{todo}"
                        }
                    }
                ))}
            }
            input {
                placeholder: "Add a new todo",
                value: "{new_todo}",
                oninput: move |evt| new_todo.set(evt.value().clone()),
            }
            button { onclick: add_todo, "Add Todo" }
        }
    }
}

前述した Dioxus hooks を使って、最低限のコードで仕上げました。
use_signalというフックスは状態を維持するためのものです。
(以前までは use_stateという名前のフックスが存在したっぽい感じがしました。)

今回は一旦(笑)TODOアプリができたということで、ここまでとしたいと思います。

おわりに

プロジェクト作成時に、tailwind css を選択したつもりでしたが、
styleプロパティに記述しても動いていなかったので 、なんとなく設定が必要そうな感じがしました。

次回の記事では tailwind css についても触れつつ、デザインをもう少しカッチョイイ感じに仕上げていこうと思います!

では。

コラボスタイル Developers

Discussion