如何在BlocBuilder内为SharedPreferences调用setState而不导致无限循环?

时间:2019-05-07 15:48:25

标签: flutter sharedpreferences setstate

我有一个StatefulWidget,需要检索存储在SharePreferences中的用户帐户变量,以便以小部件的显示和修改形式显示其所有数据。

我能够读取和显示表单中的这些变量,但是更新帐户和SharedPreferences变量时出现了问题。使用此代码,当所有内容都已更新时,我的表单也将使用新变量进行更新。但是碰巧我遇到了无限循环,因为成功的SnackBar一次又一次弹出。

如果我没有在SnackBar之前调用_loadAccount(),则消息将显示一次。

如何纠正此无限循环?哪个组件导致此无限构建?

class AccountForm extends StatefulWidget {
  final AccountBloc accountBloc;

  AccountForm({
    Key key,
    @required this.accountBloc
  }) : super(key: key);

  @override
  State<AccountForm> createState() => _AccountFormState();
}

class _AccountFormState extends State<AccountForm> {

  Account _account;
  SharedPreferences prefs;

  @override
  void initState() {
    super.initState();    
    _loadAccount();
  }

  void _loadAccount() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    Map accountMap = json.decode(prefs.getString('account'));
    setState(() {
      _account = Account.fromJson(accountMap);
    });
  }

  @override
  Widget build(BuildContext context) {

    return _account == null ? new Container() :
    new BlocBuilder<AccountEvent, AccountState>(
      bloc: _accountBloc,
      builder: (BuildContext context, AccountState state) {
        if(state is AccountSuccess) {
          _loadAccount();
          _onWidgetDidBuild(() {
            Scaffold.of(context).showSnackBar(
              SnackBar(
                content: Text('${state.message}'),
                backgroundColor: Colors.green,
              ),
            );
          });
        }

        return new DefaultTabController(
          //...
            body: new TabBarView(
              children: <Widget>[
                new ListView( // Display form
                  children: [
                    new ListTile(
                      leading: Icon(Icons.person),
                      title: Text('Name'),
                      subtitle: Text(_account.lastName + " " + 
_account.firstName)
                    ), 
                  //...
                ),
                new Form( // Modification form
                  //...
                )
              ]
            )
          )
        );
      }
    );
  }

  void _onWidgetDidBuild(Function callback) {
    WidgetsBinding.instance.addPostFrameCallback((_) {
      callback();
    });
  }
}

1 个答案:

答案 0 :(得分:0)

不,我找不到解决方案。因此,我更改了整个事件处理系统,并改用了BLOC。有了它,效果更好,不再循环。还是谢谢你