📘
Knockout.jsの資産を壊さずReactへ移行する方法
Knockout.jsの資産を壊さずReactへ移行する方法
はじめに
Knockout.js (以下 KO)で構築されたアプリは、年月を重ねるごとにUIの古さが目立ってきます。
ただ、全面的なReactへの移行は、技術資産の両立やコストパフォーマンスの問題から、そんなに簡単なことではありません。
react-ko は、KOのテンプレートやViewModelを残したまま、部分的にReactを実装していくためのライブラリです。
KOを使い続けることを前提に、Reactのコンポーネントを導入していく手段について解説します。
KOからReactへの移行における問題点
- KOのテンプレートを全部書き換えるのはリスクが大きい
- ViewModelの構築が完全にMVVM性を前提としており、Reactの持つデータフローと合わせにくい
- KOの個別observableに対した対応は多くのコードを要する
react-ko でできること
- KOの
data-bind
はそのままに、ビューだけReact化 - ViewModelをpropsとしてReactに渡し、KOのobservableを直接呼び出して使える
- KO側では
<KnockoutScope viewModel={viewModel}>
によりスコープ制御可能
インストール方法
npm install react-ko knockout
使用例(JSX / TSX 共通)
全体構成
import ko from 'knockout'
import { RootKnockoutProvider, KnockoutScope } from 'react-ko'
const viewModel = {
name: ko.observable('Alice')
}
<RootKnockoutProvider viewModel={viewModel}>
<KnockoutScope viewModel={viewModel}>
<input data-bind="value: name" />
</KnockoutScope>
</RootKnockoutProvider>
Reactコンポーネント例(JavaScript / JSX)
import { KnockoutScope } from 'react-ko'
export function KoInput({ value }) {
const vm = { value }
return (
<KnockoutScope viewModel={vm}>
<input data-bind="value: value" />
</KnockoutScope>
)
}
Reactコンポーネント例(TypeScript / TSX)
import { KnockoutScope } from 'react-ko'
type Props = {
value: KnockoutObservable<string>
}
export function KoInput({ value }: Props) {
const vm = { value }
return (
<KnockoutScope viewModel={vm}>
<input data-bind="value: value" />
</KnockoutScope>
)
}
コンポーネントの使用例
import { KoInput } from './KoInput'
const viewModel = {
name: ko.observable('Alice')
}
<KnockoutScope viewModel={viewModel}>
<KoInput value={viewModel.name} />
</KnockoutScope>
react-koが逆転の発想を提供する
- KO側を主に、Reactを引き込む「潰さない移行」
- KOのテンプレートやViewModel構成を使い回せる
- 後続のリファクタリングや、KOを減らす運用にも適している
おわりに
KOとReactは設計思想が異なるため、スッパリ切り替える更新は小規模のスタートアップに向いていますが、大規模レガシー資産には向きません。
react-koは、その間を埋める「継承性のための道具」です。
現場にある既存のKOコードを活かしながら、少しずつ次世代のUIに移行していく選択肢として、react-koを検討してみてください。
Discussion