设置变量错误状态;此小部件已被卸载,因此State不再具有上下文(并且应视为已失效)



我对Flutter相当陌生,我有一个页面,我在一个搜索字段中输入两个输入,它们在不同的变量(_selectedYear_selectedSem)中,并根据输入我创建了一个url。在创建两个搜索字段并运行它时,如果我在第一个字段之前输入第二个字段,我没有错误,但如果我在第二个字段之前输入第一个字段,这个错误会弹出。

这个小部件已经卸载,所以State不再有上下文(应该有)考虑破产)。考虑在处理期间取消任何活动的工作,或者使用挂载的getter来确定状态是否仍处于活动状态。

页面截图:

代码如下:

class _TestrState extends State<Testr> {
String _selectedYear;
String _selectedSem;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
elevation: 0,
backgroundColor: Colors.white,
title: const Text(
'Testr',
style: TextStyle(
color: Colors.black,
),
),
flexibleSpace: Container(
decoration: const BoxDecoration(
gradient: LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.bottomRight,
colors: [Colors.green, Colors.limeAccent])),
),
),
body: Container(
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
height: MediaQuery.of(context).size.height * 0.64,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Padding(
padding: EdgeInsets.all(20.0),
child: Text(
'Select a Year',
style: TextStyle(fontSize: 16, color: Colors.blueGrey),
),
),
Container(
width: double.infinity,
margin: const EdgeInsets.symmetric(horizontal: 20),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.2),
blurRadius: 10,
offset: const Offset(0, 10),
),
],
),
child: SearchField(
hint: 'Search for Year',
searchInputDecoration: InputDecoration(
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.blueGrey.shade200,
width: 1,
),
borderRadius: BorderRadius.circular(10),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
width: 2,
color: Colors.blue.withOpacity(0.8),
),
borderRadius: BorderRadius.circular(10),
),
),
maxSuggestionsInViewPort: 4,
itemHeight: 50,
suggestionsDecoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
),
onTap: (value) {
setState(() {
_selectedYear = value;
});
if (kDebugMode) {
print(value);
}
},
suggestions: const [
'Year One',
'Year Two',
'Year Three',
'Year Four',
],
),
),
const Padding(
padding: EdgeInsets.all(20.0),
child: Text(
'Select a Semester',
style: TextStyle(fontSize: 16, color: Colors.blueGrey),
),
),
Container(
width: double.infinity,
margin: const EdgeInsets.symmetric(horizontal: 20),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.2),
blurRadius: 10,
offset: const Offset(0, 10),
),
],
),
child: SearchField(
hint: 'Search for Semester',
searchInputDecoration: InputDecoration(
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.blueGrey.shade200,
width: 1,
),
borderRadius: BorderRadius.circular(10),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
width: 2,
color: Colors.blue.withOpacity(0.8),
),
borderRadius: BorderRadius.circular(10),
),
),
maxSuggestionsInViewPort: 4,
itemHeight: 50,
suggestionsDecoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
),
onTap: (value) {
setState(() {
_selectedSem = value;
});
if (kDebugMode) {
print(value);
}
},
suggestions: const [
'Afghanistan',
'Turkey',
'Germany',
'France',
'Italy',
],
),
),
],
),
),
Container(
height: 90,
padding: const EdgeInsets.only(right: 20, left: 20, bottom: 20),
decoration: const BoxDecoration(
color: Colors.white,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
_selectedYear == null
? const Text(
'Select a Year and a Semester to Continue',
style:
TextStyle(fontSize: 14, color: Colors.blueGrey),
)
: Text(_selectedYear + "->" + _selectedSem,
style: TextStyle(
fontSize: 16,
color: Colors.grey.shade800,
fontWeight: FontWeight.w600)),
MaterialButton(
onPressed: () {
CreateURL(_selectedYear, _selectedSem);
},
color: Colors.black,
minWidth: 50,
height: 50,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(50),
),
padding: const EdgeInsets.all(0),
child: const Icon(
Icons.arrow_forward_ios,
color: Colors.blueGrey,
size: 24,
),
)
],
),
)
],
),
),
),
);
}
}

我试着把setstate放在'if(mounted)'中,在看了其他类似的问题后,这不起作用。

我只是改变了变量初始化,它工作。

String _selectedYear = "";
String _selectedSem = "";

并将此逻辑添加到setState

setState(() {
_selectedSem = value!;
});

这个对我很有用,试一下,看看

我不确定,但一旦你尝试这种方式。首先,将值初始化为一个变量,然后刷新状态

_selectedYear = value!;
setState(() {});

或者如果您使用的是flutter 2.5.3或更高版本,则需要初始化变量或迁移到null安全。

最新更新