You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Flutter Riverpod实现页面传参及单篇文章数据获取的问题

解决Flutter Riverpod路由传参及API请求参数传递问题

问题背景

使用Flutter结合flutter_riverpod开发应用,习惯了GetX的路由传参方式,对Riverpod不熟悉。现有三个核心文件:

  • AAmain.dart:首页,通过HTTP请求获取文章列表并展示
  • AAx2.dart:文章详情页,展示单篇文章的图片、标题等内容
  • AAapi.dart:仅包含获取单篇文章数据的HTTP请求函数fetch_1WpPosts

核心问题:点击首页文章项跳转详情页时,无法将文章slug参数传递给AAapi.dart——该文件没有ProviderScope、ref或WidgetRef,导致fetch_1WpPosts无法获取状态拼接请求URL。


解决方案

1. 重构AAapi.dart:让API函数直接接收参数

移除对Riverpod ref的依赖,将slug作为参数传入API函数,这是最直接的方式,避免不必要的状态依赖:

import 'package:http/http.dart' as http;
import 'dart:convert';

Future<List<dynamic>> fetch_1WpPosts(String slug) async {
  final baseUrl = 'https://meshcurrent.online/wp/wp-json/api/v1/posts/';
  final requestUrl = '$baseUrl$slug';

  final response = await http.get(Uri.parse(requestUrl));
  List<dynamic> convertDataJson = jsonDecode(response.body);

  return convertDataJson;
}

2. 修改AAmain.dart:跳转时传递slug参数

删除无效的StateProvider定义,通过路由直接传递slug参数到AAx2页面:

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'wp-api.dart';
import 'AAx2.dart';
import 'package:flutter_eem_1/custom.dart';

void main() {
  runApp(const ProviderScope(child: benimApp0()));
}

class benimApp0 extends ConsumerWidget {
  const benimApp0({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    return MaterialApp(
      theme: ThemeData(),
      home: const Scaffold(
        body: SafeArea(
          child: xMyHomePage(),
        ),
      ),
    );
  }
}

class xMyHomePage extends ConsumerWidget {
  const xMyHomePage({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    return Scaffold(
      body: Column(
        children: [
          Expanded(
            child: FutureBuilder<List<dynamic>>(
              future: fetchWpPosts(),
              builder: (context, snapshot) {
                if (snapshot.hasData) {
                  return ListView.builder(
                    itemCount: 5,
                    itemBuilder: (BuildContext context, int index) {
                      final postSlug = snapshot.data![index]["slug"];
                      return InkWell(
                        onTap: () {
                          Navigator.of(context).push(
                            MaterialPageRoute(
                              builder: (context) => x2(postSlug: postSlug),
                            ),
                          );
                        },
                        child: Column(
                          children: [
                            Image.network(
                              snapshot.data![index]["featured_image"]["large"].toString(),
                            ),              
                          ],
                        ),
                      );
                    },
                  );
                }
                return const Center(child: CircularProgressIndicator());
              },
            ),
          ),
        ],
      ),
    );
  }
}

3. 修改AAx2.dart:接收路由参数并传递给API

修改x2组件,添加接收slug的构造函数,在FutureBuilder中传递参数给fetch_1WpPosts:

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_eem_1/AAapi.dart';

class x2 extends ConsumerWidget {
  final String postSlug;

  const x2({super.key, required this.postSlug});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    return Scaffold(
      body: SafeArea(
        child: SingleChildScrollView(
          child: FutureBuilder<List<dynamic>>(
            future: fetch_1WpPosts(postSlug),
            builder: (context, snapshot) {
              if (snapshot.hasData) {
                final post = snapshot.data![0];
                return Column(
                  children: [
                    Text(
                      post["title"],
                      style: const TextStyle(
                        fontSize: 25,
                        fontWeight: FontWeight.bold,
                      ),
                    ),
                    Image.network(post["featured_image_large"]),
                  ],
                );
              } else if (snapshot.hasError) {
                return Center(child: Text('加载失败: ${snapshot.error}'));
              }
              return const Center(child: CircularProgressIndicator());
            },
          ),
        ),
      ),
    );
  }
}

(可选)用Riverpod FutureProvider封装API请求(最佳实践)

如果想利用Riverpod的状态管理能力自动处理加载、错误状态,可以将API请求封装为FutureProvider:

第一步:在AAapi.dart中定义Provider

import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';

final singlePostProvider = FutureProvider.family<List<dynamic>, String>((ref, slug) async {
  final baseUrl = 'https://meshcurrent.online/wp/wp-json/api/v1/posts/';
  final requestUrl = '$baseUrl$slug';

  final response = await http.get(Uri.parse(requestUrl));
  return jsonDecode(response.body);
});

第二步:修改AAx2.dart使用Provider

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_eem_1/AAapi.dart';

class x2 extends ConsumerWidget {
  final String postSlug;

  const x2({super.key, required this.postSlug});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final postAsyncValue = ref.watch(singlePostProvider(postSlug));

    return Scaffold(
      body: SafeArea(
        child: postAsyncValue.when(
          loading: () => const Center(child: CircularProgressIndicator()),
          error: (error, stack) => Center(child: Text('加载失败: $error')),
          data: (postData) {
            final post = postData[0];
            return SingleChildScrollView(
              child: Column(
                children: [
                  Text(
                    post["title"],
                    style: const TextStyle(
                      fontSize: 25,
                      fontWeight: FontWeight.bold,
                    ),
                  ),
                  Image.network(post["featured_image_large"]),
                ],
              ),
            );
          },
        ),
      ),
    );
  }
}

内容的提问来源于stack exchange,提问作者mesh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 18:45:31