Zenn
📘

Knockout.jsの資産を壊さずReactへ移行する方法

2025/03/28に公開

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

GitHub リポジトリはこちら


使用例(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

ログインするとコメントできます