将参数传递给 initState
Posted
技术标签:
【中文标题】将参数传递给 initState【英文标题】:Pass parameter to initState 【发布时间】:2019-07-28 00:02:36 【问题描述】:查看这段代码 - 获取数据并显示在列表中的小部件:
class _MyEventsFragmentState extends State <MyEventsFragment>
var events;
@override
initState()
super.initState();
events = fetchEvents(true);
@override
Widget build(BuildContext context)
return new Center(
child: FutureBuilder<EventsResponse>(
future: events,
builder: (context, snapshot)
if (snapshot.connectionState == ConnectionState.done)
if (snapshot.hasError)
helpers.logout(context, Strings.msg_session_expired);
return CircularProgressIndicator();
return new Container(color: Colors.white,
child: new ListControl().build(snapshot));
return CircularProgressIndicator();
,
)
);
fetchEvent
方法有参数来指示我需要获取哪些事件。如果设置为 true, - 我的事件,如果设置为 false - 返回所有事件。上面的代码会加载我的事件,并在 initState
覆盖内调用 fetchEvents
以避免不必要的数据重新加载。
为了获取所有事件,我定义了另一个类:
class EventsFragment extends StatefulWidget
@override
_EventsFragmentState createState() => new _EventsFragmentState();
class _EventsFragmentState extends State <EventsFragment>
var events;
@override
initState()
super.initState();
events = fetchEvents(false);
@override
Widget build(BuildContext context)
return new Center(
child: FutureBuilder<EventsResponse>(
future: events,
builder: (context, snapshot)
if (snapshot.connectionState == ConnectionState.done)
if (snapshot.hasError)
helpers.logout(context, Strings.msg_session_expired);
return CircularProgressIndicator();
return new Container(color: Colors.white,
child: new ListControl().build(snapshot));
return CircularProgressIndicator();
,
)
);
但这是非常愚蠢的解决方案,因为代码几乎相同。所以我尝试传递布尔值来指示要加载哪些事件,如下所示:
@override
initState()
super.initState();
events = fetchEvents(isMyEvents);
isMyEvents
应该从EventsFragment
构造函数中获得。但是,在 initState
内无法访问它。何能正确通过呢?我可以在build
覆盖内访问它,但不能在initState
内访问。如何正确传递并确保每次创建小部件实例时都会刷新?
[编辑]
所以这就是我解决问题的方法(看起来没问题):
class EventsFragment extends StatefulWidget
const EventsFragment(Key key, this.isMyEvent) : super(key: key);
final bool isMyEvent;
@override
_EventsFragmentState createState() => new _EventsFragmentState();
class _EventsFragmentState extends State <EventsFragment>
var events;
@override
initState()
super.initState();
events = fetchEvents(widget.isMyEvent);
@override
void didUpdateWidget(EventsFragment oldWidget)
if(oldWidget.isMyEvent != widget.isMyEvent)
events = fetchEvents(widget.isMyEvent);
super.didUpdateWidget(oldWidget);
@override
Widget build(BuildContext context)
return new Center(
child: FutureBuilder<EventsResponse>(
future: events,
builder: (context, snapshot)
if (snapshot.connectionState == ConnectionState.done)
if (snapshot.hasError)
helpers.logout(context, Strings.msg_session_expired);
return CircularProgressIndicator();
return new Container(color: Colors.white,
child: new ListControl().build(snapshot));
return CircularProgressIndicator();
,
)
);
【问题讨论】:
将你的参数保存为final
EventsFragment
中的字段
无法从状态访问
是的,它会的,见State#widget
property
【参考方案1】:
将此类参数传递给StatefulWidget
子类,并改用该字段
class Foo extends StatefulWidget
const Foo(Key key, this.isMyEvent) : super(key: key);
final bool isMyEvent;
@override
_FooState createState() => _FooState();
class _FooState extends State<Foo>
@override
void initState()
super.initState();
print(widget.isMyEvent);
@override
Widget build(BuildContext context)
return Container(
);
【讨论】:
initState()
仅被调用一次,因此如果我第一次将 isMyEvent 传递为 true,然后第二次传递为 false,我的数据将不会被刷新。如何从我的小部件外部强制重置状态?
我的意思是颤振缓存我的小部件。因此,如果我想再次显示它,更改 isMyEvent
值,仍然会使用以前的 isMyEvent
值刷新数据。
使用didUpdateWidget
怎么用?我将didUpdateWidget(widget);
添加到initState
,但我仍然遇到同样的问题
我更新了我的问题,如果它是有效的解决方案,请告诉我。以上是关于将参数传递给 initState的主要内容,如果未能解决你的问题,请参考以下文章