我正在使用 Flutter 并尝试使用 FutureBuilder 根据 Provider 包管理的状态来获取数据。我面临的挑战是我的未来取决于我可以通过
Provider.of<MyData>(context)
进入的状态。
问题来了:
我目前的方法:
class MyWidget extends StatelessWidget {
final Future<DataType> future;
MyWidget() : future = fetchData(); // This can't access context
@override
Widget build(BuildContext context) {
final myData = Provider.of<MyData>(context); // Need to use myData here
// Creating the Future here causes it to recompute on every build
final future = fetchDataBasedOn(myData);
return FutureBuilder<DataType>(
future: future,
builder: (context, snapshot) {
// Build your widget based on snapshot
},
);
}
}
我的问题: 我如何以只计算一次的方式管理 Future,并且仍然能够访问提供者的状态?是否有推荐的模式可以使用 Flutter 的 FutureBuilder 和 Provider 来实现这一目标?
任何建议或示例将不胜感激!
可以使用initState,initState仅用于在创建widget时初始化Future一次。
示例:
Future<DataType>? future;
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((callback) {
final data = Provider.of<YourProvider>(context);
setState(() {
future = fetchData(data);
});
});
}
然后在您使用的 FutureBuilder 中使用 future。
class MyWidget extends StatefulWidget {
@override
_MyWidgetState createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
Future<DataType> future;
@override
void didChangeDependencies() {
super.didChangeDependencies();
// Initialize the future in
didChangeDependencies
future = fetchDataBasedOn(Provider.of<MyData>(context, listen: false));
}
@override
Widget build(BuildContext context) {
return FutureBuilder<DataType>(
future: future,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return CircularProgressIndicator();
} else if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
} else {
return Text('Data: ${snapshot.data}');
}
},
);
}
}
你可以这样使用,希望对你有帮助。
> you can use init() method to manage future and it compute only once and also you can access provider state.
- example for understanding..
/// Create getter and future variable
Demo get demoData => Provider.of(context, listen: false);
late Future<dynamic> future;
/// call getData() method
void initState() {
super.initState();
getData();
}
/// in this method you can initialized futureVariable and also manage provider state and you can use future in futureBuilder alse
getData() async {
future = await fetchData(demoData);
}