Stateをリフトアップする
CoddyのFlutterジャーニー「状態管理」セクションの一部。レッスン 4/27。
スマートフォンの親指ボタンをタップすると、その横の数字は増えますが、上部バーにはまだ0 likesと表示されています。ボタンは自分自身のStateにカウントを保持していて、ほかのものからは見ることができません。
2つのウィジェットで同じ値が必要な場合は、それら両方を含む最も近いウィジェットまで状態を引き上げます。これを状態の引き上げと呼びます。ページがlikesを所有し、ボタンは値とコールバックを受け取るStatelessWidgetになります。
LikeButton(
likes: likes,
onLike: () {
setState(() {
likes++;
});
},
)これで、カウントは1か所に1つだけあります。上部バー、ボタン、リセットボタンはすべて、その同じ値を読み取り、変更するため、食い違うことはありません。
簡単なテスト方法:値が2か所で表示または変更される場合、その値を所有するウィジェットは、その両方より上位になければなりません。
チャレンジ
中級「いいね」の唯一の管理者をページにします。
LikeButtonを、likesとonLikeコールバックの2つのフィールドを持つStatelessWidgetに変更します。- ページ自身の
likesと、setState内で1を加算するonLikeを渡します。
すると、トップバーはボタンに連動し、更新ボタンは両方をリセットします。
自分で試してみよう
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
debugShowCheckedModeBanner: false,
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
int likes = 0;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('$likes likes'),
actions: [
IconButton(
icon: const Icon(Icons.refresh),
onPressed: () {
setState(() {
likes = 0;
});
},
),
],
),
body: const Center(
child: LikeButton(),
),
);
}
}
class LikeButton extends StatefulWidget {
const LikeButton({super.key});
@override
State<LikeButton> createState() => _LikeButtonState();
}
class _LikeButtonState extends State<LikeButton> {
int likes = 0;
@override
Widget build(BuildContext context) {
return Row(
mainAxisSize: MainAxisSize.min,
children: [
IconButton(
icon: const Icon(Icons.thumb_up),
iconSize: 40,
onPressed: () {
setState(() {
likes++;
});
},
),
Text('$likes', style: const TextStyle(fontSize: 32)),
],
);
}
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
状態管理のすべてのレッスン
自分で練習してみよう: Flutterオンラインコンパイラ