Webフロントエンドの文脈から見たFlutter

菅原 孝則

Farmnote

Flutter Meetup Tokyo #7

Farmnote

STUDIO

Flutter歴
3週間

2000年頃から
UIデザイン・実装してるおっさんです

主な対象者

Flutterに興味あるフロントエンドエンジニア
社内のWeb人材をネイティブに寄せたい人

特に重要なのを紹介

Flash

クロスプラットホームで
描画内容が一致する優れもの

Ajaxより先に非同期通信でUIが作れていたり

OSやブラウザが違ってもほぼ同じ見た目なので
レイアウトの崩れが起きにくく楽だった。
様々な表現の母体になるもジョブズさんに死刑宣告

.Net 3.0 / WPF

MVVMをUIに最初に持ち込んだ
Componentをマークアップ
Rx発祥の地

現在のUI実装の祖となる偉大な設計にも関わらず
設計思想のあまりの飛躍とVistaのパフォーマンスの悪さで
今ひとつ流行らなかった

React

仮想Domと言う偉大な発明により
WPFから7年ぶりにUI界隈に進化をもたらした

日本だとVue.jsに押されてますが、英語圏では圧倒的シェア

React Native

モバイルアプリ界隈に
クロスプラットホーム開発で
ようやく現実的なソリューションを提供した。

ホットリロードで開発できるの最高でした
バージョンアップが活発でパッケージが
軒並みゾンビ化するので、最後に頼れるのは自分

Flutter

クロスプラットホーム
ホットリロード
共通の描画内容
結構早い描画処理

描画内容が同じなのはFlashと同じ
ホットリロードで開発できるはRNと同じ
仮想Domっぽい仕組みはReactと同じ

Flutterで
進化している点

レンダリングの判定がイイ

Reduxなどでは行えない
変数レベルでObservableな管理が可能

const store = {
    state = {
        foo: 1,
        name: '何か'
    },
    update(cb) {
        this.state = cb(this.state);
    }
};
const {Provider, Consumer} = React.createContext(store.state);
const Foo = () => (
<Consumer>
    {({foo, name}) => (
        <div>
            <p>Foo is {foo}</p>
            <div>{name}</div>
        </div>
    )}
</Consumer>
);
const App = () => (
<Provider value={store.state}>
    <Foo />
</Provider>
);

Reactだとこんな感じ

const {Provider, Consumer} = React.createContext(store.state);
const Foo = () => (
<Consumer>
    { store => (
        <div>
            <p>Foo is {store.foo}</p>
            <div>{store.name}</div>
        </div>
    )}
</Consumer>
);
const App = () => (
<Provider value={store.state}>
    <Foo />
</Provider>
);

Text

変数レベルでは変更検知できない

Flutterならできる

Streamで
変数レベルの変更検知

const store = {
    state = {
        foo: 1,
        name: '何か'
    },
    update(cb) {
        this.state = cb(this.state);
    }
};
class Bloc {
    final _fooControlelr = StreamController<String>();
    get foo => _fooControlelr.stream;
    Sink<String> updateFoo => _fooControlelr.sink;

    final _nameControlelr = StreamController<String>();
    get name => _nameControlelr.stream;
    Sink<String> updateName => _nameControlelr.sink;

    Bloc() {
        updateFoo.add('foo');
        updateName.add('何か')
    }
}

Flutter

React

まずはこんなもん

StreamBuilder

Reduxなどでは行えない
変数レベルでObservableな管理が可能

class Foo extends StatelessWidget {
    @override
    build(context) {
        final bloc = BlocProvider.of(context);
        return Column( children: [
                StreamBuilder<String>(
                    stream: bloc.foo,
                    builder(context, snapshot) => Text('Foo is ${snapshot.data}')
                )
                StreamBuilder<String>(
                    stream: bloc.name,
                    builder(context, snapshot) => Text('Foo is ${snapshot.data}')
                )
            ]
        );
    }
}

class App extends StatelessWidget {
    @override
    build(context) {
        return BlocProvider(
            child: Foo()
        );
    }
}

変数レベルでレンダリングできる

Reactから

一歩前進してる

状態管理周り

Flutter React Vue
StatelessWidget SFC SFC
StateFullWidget 普通のコンポーネント 普通のコンポーネント
InheritedWidget Context Provide/Inject
Redux Redux
ScopedModel MobX VueX
BloC ない ない

状態管理比較

Angularはよくわかってないので書けませんでした

とまぁ大体対比はわかりましたね!

詳しい事は先人に
学びましょう

こんな感じで作ってます

ReactNativeと似てるよね

OTAとJsで作れるのがRNのいいところ。


その他はFlutterの方が楽です。

ファームノートは

Flutterできる人や
Vueできる人や
ReactNativeできる人が働いています。

興味あったらWantedlyのぞいてね!

ありがとうございました

Webフロントエンドの文脈から見たFlutter

By sugawara takanori

Webフロントエンドの文脈から見たFlutter

  • 4,632