ข้ามไปยังเนื้อหา

setState vs useState

ใน React useState คือ hook ที่เก็บค่าและคืน setter กลับมา เรียก setter แล้ว React จะกำหนดเวลา re-render และ component function จะทำงานอีกครั้งพร้อมค่าใหม่ state อยู่ใน slot ซ่อนอยู่ที่ผูกกับ component instance

Flutter ใช้ setState(() { ... }) เป็นเทียบเท่า แต่ก่อนจะเรียกได้ คุณต้องมีสอง class แทนที่จะเป็นหนึ่ง — คือ StatefulWidget และ State<T> การแยกนี้ดูยาวเหนื่อยตอนแรก แต่แก้ปัญหาเฉพาะ: widget objects ใน Flutter เป็น immutable และ framework สามารถสร้างใหม่ได้ราคาถูก State object อยู่ได้นานกว่าและเก็บข้อมูลที่เปลี่ยนแปลงได้จริง

React
import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>
Increment
</button>
</div>
);
}
Flutter
class Counter extends StatefulWidget {
const Counter({super.key});
@override
State<Counter> createState() => _CounterState();
}
class _CounterState extends State<Counter> {
int _count = 0; // state อยู่ที่นี่
void _increment() {
setState(() { // ครอบ mutation
_count++;
});
}
@override
Widget build(BuildContext context) {
return Column(
children: [
Text('Count: $_count'),
ElevatedButton(
onPressed: _increment,
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 MaterialApp(
      title: 'Counter',
      theme: ThemeData(colorScheme: ColorScheme.fromSeed(seedColor: Colors.indigo)),
      home: const 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;

  void _increment() => setState(() => _count++);
  void _decrement() => setState(() => _count--);
  void _reset()     => setState(() => _count = 0);

  @override
  Widget build(BuildContext context) {
    final scheme = Theme.of(context).colorScheme;
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        Text(
          '$_count',
          style: TextStyle(
            fontSize: 72,
            fontWeight: FontWeight.bold,
            color: scheme.primary,
          ),
        ),
        const SizedBox(height: 24),
        Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            FilledButton.tonal(onPressed: _decrement, child: const Text('−')),
            const SizedBox(width: 12),
            FilledButton(onPressed: _increment, child: const Text('+')),
            const SizedBox(width: 12),
            OutlinedButton(onPressed: _reset, child: const Text('Reset')),
          ],
        ),
      ],
    );
  }
}
setState() ของ Flutter ทำอะไรที่ต่างจาก setter ของ useState ใน React?
createState() ถูกเรียกกี่ครั้งสำหรับ Counter widget instance เดียว?
Mutable state fields ใน Flutter StatefulWidget อยู่ที่ไหน?
เทียบเท่า React ของ State<T>.build() ใน Flutter คืออะไร?