Navigation — ภาพรวมโมดูล
ใน React การนำทางมักขับเคลื่อนด้วย URL โดย react-router จับคู่ path กับ component, browser history API บันทึกการเยี่ยมชมแต่ละครั้ง และผู้ใช้สามารถ deep-link ไปยังหน้าใดก็ได้ด้วยการพิมพ์ที่อยู่ Flutter ใช้แนวทางต่างออกไป โดยค่าเริ่มต้น Flutter ใช้ stack แบบ imperative ที่จัดการโดย Navigator widget — คุณ push route เข้า stack และ pop ออก คล้ายกับการเรียก history.push และ history.back ใน plain JavaScript แต่ไม่มี URL เข้ามาเกี่ยวข้องบนมือถือ
ทั้งสองโมเดลมาบรรจบกันในสถานการณ์ web และ deep-linking แพ็กเกจ go_router ของ Flutter (ครอบคลุมในบทเรียนของตัวเอง) นำ declarative routing แบบ URL-based มาซึ่งตรงกับ react-router v6 เกือบทุกประการ
โมดูลนี้ครอบคลุมอะไรบ้าง
หัวข้อที่มีชื่อว่า “โมดูลนี้ครอบคลุมอะไรบ้าง”| บทเรียน | แนวคิด Flutter | สิ่งที่เทียบได้ใน React |
|---|---|---|
| พื้นฐาน Navigator | Navigator.push / .pop | useNavigate, history.push |
| Named routes | routes: map + pushNamed | <Routes> + <Route path="..."> |
| go_router | GoRouter, GoRoute | react-router v6 createBrowserRouter |
| การส่งข้อมูล | Constructor args, await pop | Route state, useParams, callbacks |
| Tabs & Drawer | BottomNavigationBar, Drawer | Tab libs, sidebar components |
ภาพรวมแบบรันได้: push และ pop
หัวข้อที่มีชื่อว่า “ภาพรวมแบบรันได้: push และ pop”ตัวอย่างด้านล่างแสดง primitive การนำทางหลักของ Flutter: Navigator.push รับ BuildContext และ Route object, push หน้าจอใหม่เข้า stack, และ Flutter เชื่อมต่อปุ่มย้อนกลับให้อัตโนมัติ Navigator.pop กลับไปยังหน้าจอก่อนหน้า
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: HomeScreen(),
);
}
}
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Home')),
body: Center(
child: ElevatedButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (_) => const DetailScreen()),
);
},
child: const Text('Go to Detail'),
),
),
);
}
}
class DetailScreen extends StatelessWidget {
const DetailScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Detail')),
body: Center(
child: ElevatedButton(
onPressed: () => Navigator.pop(context),
child: const Text('Go Back'),
),
),
);
}
}