はじめに
Riverpod は状態管理パッケージです。フロントエンドエンジニアの方なら1度は聞いたことがある Recoil と設計が似ているため、この記事では Riverpod と Recoil を比べていきます。
本題
使用するための準備
Recoil では RecoilRoot の設定を行います。
src/main.tsx
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import "./index.css";
import { RecoilRoot } from "recoil";
ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
<React.StrictMode>
<RecoilRoot>
<App />
</RecoilRoot>
</React.StrictMode>
);
Riverpod では ProviderScope の設定を行います。
lib/main.dart
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
void main() {
runApp(
const ProviderScope(
child: MyApp(),
),
);
}
ステートの作成
Recoil では Atom を使用してステートを作成します。
src/states/count.ts
import { atom } from "recoil";
export const countState = atom({
key: "countState",
default: 0,
});
Riverpod では Provider を使用して作成します。今回は StateProvider を使用します。
lib/data/provider/count_provider.dart
import 'package:flutter_riverpod/flutter_riverpod.dart';
final countProvider = StateProvider<int>((_) => 0);
ステートの取得・更新
Recoil では useRecoilState を使用してステートを取得します。また、変更するための関数も useRecoilState を使用して取得します。
src/components/Counter/index.tsx
import { useRecoilState } from "recoil";
import { countState } from "../../states/count";
export const Counter = () => {
const [count, setCount] = useRecoilState(countState);
return (
<div>
<div>count: {count}</div>
<button type="button" onClick={() => setCount((prev) => prev + 1)}>
add
</button>
</div>
);
};
Riverpod では ConsumerWidget を継承したウィジェットを作成し、 WidgetRef を使用してステートを取得します。また、変更する際は update
関数を使用します。
lib/ui/components/counter.dart
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:sample/data/provider/count_provider.dart';
class Counter extends ConsumerWidget {
const Counter({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final count = ref.watch(countProvider);
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'count: $count',
),
TextButton(
onPressed: () {
ref.read(countProvider.notifier).update((state) => state + 1);
},
child: const Text(
'add',
),
)
],
),
);
}
}
おわりに
比べてみるとかなり似ていることが分かります。 Recoil を使用したことがある方はぜひ Riverpod を使用してみることをおすすめします。