我正在学习颤振。我编写了一个小应用程序来从 API 获取密钥并将其打印在屏幕上。问题是我的getApiKey()方法是循环的。
为什么?我该如何预防?
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'package:provider/provider.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: ChangeNotifierProvider<TenderApiData>(
builder: (_) => TenderApiData(), child: HomePage()),
);
}
}
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(appBar: AppBar(), body: MyContainer());
}
}
class MyContainer extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[MyTestWidget()],
);
}
}
class TenderApiData with ChangeNotifier {
String access_token;
String url = "https://";
getApiKey() async
{
var response = await http.post(url, headers: {"Accept": "application/json"});
// await Future.delayed(Duration(seconds: 25));
if (response.statusCode == 200)
{
access_token = json.decode(response.body)['access_token'];
notifyListeners();
}
}
}
class MyTestWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
Provider.of<TenderApiData>(context).getApiKey();
var result = Provider.of<TenderApiData>(context).access_token;
return Row(
children: <Widget>[
Flexible(child: Text("Data: $result"))
],
);
}
}
Run Code Online (Sandbox Code Playgroud)
发生这种情况的原因是您在getApiKey函数中通知侦听器,然后在方法中调用 。当您通知您的听众时会调用该方法,看看为什么会循环?getApiKeybuildbuild
不管怎么说,以防止它,您只需将您StatelessWidget的StatefulWidget只有调用getApiKey的State.didChangeDependencies(不是initState因为你需要访问BuildContext):
class MyTestWidget extends StatefulWidget {
@override
_MyTestWidgetState createState() => _MyTestWidgetState();
}
class _MyTestWidgetState extends State<MyTestWidget> {
bool apiKeyLoaded;
@override
void initState() {
apiKeyLoaded = false;
super.initState();
}
@override
void didChangeDependencies() {
if (!apiKeyLoaded) {
Provider.of<TenderApiData>(context).getApiKey();
apiKeyLoaded = true;
}
super.didChangeDependencies();
}
@override
Widget build(BuildContext context) {
var result = Provider
.of<TenderApiData>(context)
.access_token;
return Row(
children: <Widget>[
Flexible(child: Text("Data: $result"))
],
);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
674 次 |
| 最近记录: |