【发布时间】:2021-11-17 03:19:18
【问题描述】:
背景
在我的有状态小部件的状态对象中,我有以下代码。
class _PendingJobsState extends State<PendingJobs> {
List<String> pendingJobs = []; <------------------- I am trying to change the state of this variable.
void updateListWithResponseData(List jobs) {
BackendApi.call(
endpoint: APIEndPoints.GET_PENDING_JOBS,
data: {"email": GlobalData.userEmail},
onSuccess: (data) {
setState(() { <---------------- I call set State here
jobs = data['job_list'];
print(pendingJobs); <------------ State is not changed
print(jobs);
});
},
onFailed: (error) {
print('Failed to fetch data!');
});
}
@override
void initState() {
updateListWithResponseData(pendingJobs); <------- This is where the function in which I call the setState is executed.
super.initState();
}
关于上述代码的详细信息
???? List<String> pendingJobs = []; 是我期望完成状态更改的变量。
????在上述变量updateListWithResponseData 正下方定义的函数采用List 类型的参数。它还负责调用另一个名为BackendApi.call() 的实用程序函数。
????我在initState 中调用udateListWithResponseData(),对于List 类型的参数,我给出了我定义的pendingJobs 变量。 (由于我是从updateListWithResponseData() 函数中调用setState,我希望pendingJobs 的状态在调用updateListWithResponseData 时会发生变化。)
???? 但是,我在上面所期望的状态变化并没有发生。
???? BackendApi.call 负责从给定的 url 中获取数据,它为 onSuccess 和 onFailure 提供两个回调函数,它们负责根据数据获取是否成功执行必要的操作。
重要说明
从updateListWithResponseData 中删除List jobs 参数并直接引用pendingJobs 变量对我来说是不是解决方案,因为我希望提取调用 updateListWithResponseData 的函数到一个单独的 dart 文件并从不同的小部件调用它。 所以我必须在函数中有 List jobs 参数。
我尝试调试此问题一段时间,但找不到解决方案。如果有人能指出为什么pendingJobs 的状态没有改变以及如何真正改变它,那将非常有帮助。 (谢谢。)
**编辑**
由于下面的许多 cmets 似乎都围绕 BackendApi.call() 函数,并且由于我没有在我的原始帖子中包含该函数的代码,所以我编辑了这篇文章以包含该代码。
import 'dart:convert';
import 'package:field_app/globalData/global_data.dart';
import 'package:http/http.dart' as http;
import 'api_endpoints.dart';
typedef ValueChanged<T> = void Function(T value);
class BackendApi {
static void call(
{String endpoint,
Map<String, dynamic> data,
ValueChanged<Map<String, dynamic>> onSuccess,
ValueChanged<String> onFailed}) async {
try {
var response = await http.post(APIEndPoints.API_ROOT + endpoint,
headers: {
"Content-Type": "application/json",
"Authorization": 'Bearer ' + GlobalData.authToken,
},
body: jsonEncode(data));
Map<String, dynamic> apiResponse = jsonDecode(response.body);
if (apiResponse != null) {
if (response.statusCode == 200) {
if (onFailed != null) {
onSuccess(apiResponse);
}
} else {
print(apiResponse['message']);
print('code: ' + response.statusCode.toString());
if (onFailed != null) {
onFailed(apiResponse['message']);
}
}
} else {
print('Invalid API response format');
print('code: ' + response.statusCode.toString());
return null;
}
} catch (e) {
print("Failed to connect with backend API");
print(e.toString());
return null;
}
}
}
【问题讨论】:
-
抱歉,
BackendApi.call是在使用 http 请求还是在使用某种 Future? -
@Yeasin Sheikh 是的。
Backend.call是一个异步函数,它发送post http request -
你能不能尝试使
updateListWithResponseData()异步并使用await。 -
在
setState中,您应该更改pendingJobs的值,而不是jobs。顺便说一句,FutureBuilder是一个更好的解决方案,请参阅我的回答 here。 -
@YeasinSheikh 这样做有一点问题,因为
BackendApi.call()的返回类型为void。所以我不能await它即使我将updateListWithResponseData()设为异步函数。
标签: flutter flutter-widget flutter-state flutter-build flutter-future