Declarative UI
สิ่งที่น่าโล่งใจที่สุดสำหรับ React developer ที่มาเรียน Flutter คือ declarative UI model นั้นเหมือนกันในระดับแกนหลัก — UI ของคุณคือ pure function ของ state เมื่อ state เปลี่ยน คุณ describe UI ใหม่และ framework จะหาว่าต้องอัปเดตอะไร ความแตกต่างอยู่ที่ plumbing — Flutter มี element tree และ reconciler เป็นของตัวเองแทน virtual DOM แต่ mental model ที่คุณมีอยู่แล้วนั้นถูกต้องทุกประการ
UI = f(state): แนวคิดเดียวกัน, plumbing ต่างกัน
หัวข้อที่มีชื่อว่า “UI = f(state): แนวคิดเดียวกัน, plumbing ต่างกัน”// React — declarative counterimport { useState } from 'react';
function Counter() { const [count, setCount] = useState(0);
return ( <div> <p>Count: {count}</p> <button onClick={() => setCount(c => c + 1)}> Increment </button> </div> );}// Flutter — declarative counter (StatefulWidget)class Counter extends StatefulWidget { const Counter({super.key});
@override State<Counter> createState() => _CounterState();}
class _CounterState extends State<Counter> { int _count = 0;
@override Widget build(BuildContext context) { return Column( mainAxisSize: MainAxisSize.min, children: [ Text('Count: $_count', style: const TextStyle(fontSize: 24)), ElevatedButton( onPressed: () => setState(() => _count++), child: const Text('Increment'), ), ], ); }}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(
home: Scaffold(
body: Center(
child: Counter(),
),
),
);
}
}
class Counter extends StatefulWidget {
const Counter({super.key});
@override
State<Counter> createState() => _CounterState();
}
class _CounterState extends State<Counter> {
int _count = 0;
@override
Widget build(BuildContext context) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
'Count: $_count',
style: const TextStyle(fontSize: 32, fontWeight: FontWeight.bold),
),
const SizedBox(height: 16),
ElevatedButton(
onPressed: () => setState(() => _count++),
child: const Text('Increment', style: TextStyle(fontSize: 18)),
),
const SizedBox(height: 8),
OutlinedButton(
onPressed: () => setState(() => _count = 0),
child: const Text('Reset'),
),
],
);
}
}