textfield reload issue and other things reload problem.===================================
https://github.com/flutter/flutter/issues/18828
https://blog.csdn.net/u011272795/article/details/83010974 <<<<<<<===============
https://medium.com/saugo360/flutter-my-futurebuilder-keeps-firing-6e774830bc2
Flutter: My FutureBuilder Keeps Firing!
If you’ve ever done any serious Flutter development, then you have definitely faced the problem in the title above. But don’t worry, You’re not alone!
What is the problem?
The FutureBuilder widget that Flutter provides us to create widgets based on the state of some future, keeps re-firing that future every time a rebuild happens! The problem is best manifested with this simple example:
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: HomeScreen()
);
}
}
class HomeScreen extends StatefulWidget {
@override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
bool _switchValue;
@override
void initState() {
super.initState();
this._switchValue = false;
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Switch(
value: this._switchValue,
onChanged: (newValue) {
setState(() {
this._switchValue = newValue;
});
},
),
FutureBuilder(
future: this._fetchData(),
builder: (context, snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.none:
case ConnectionState.waiting:
return Center(
child: CircularProgressIndicator()
);
default:
return Center(
child: Text(snapshot.data)
);
}
}
),
],
),
);
}
_fetchData() async {
await Future.delayed(Duration(seconds: 2));
return 'REMOTE DATA';
}
}
- Our app displays a
HomeScreenon which we have oneSwitchwidget and oneFutureBuilderthat loads remote data and displays it on the screen. - The
FutureBuildersubscribes to the future returned from the function_fetchData. This function simulates a server that returns its result after two seconds. - When the user taps the switch, we update the member
_switchValue, which is then fed into the switch itself, to change its actual value.
If you run this app, the following happens:

Flipping the switch affects the state of the FutureBuilder
Even though the switch and the FutureBuilder are not related in any form, every time we change the switch value (by calling setState), the FutureBuilder goes through its whole life-cycle again! It re-fetches the future, causing unneeded traffic, and shows the loading again, causing bad user experience.
This problem manifests itself in a variety of ways. In some cases it’s not even as obvious as the example above. For example:
- Network traffic being generated from pages that are not currently on screen
- Hot reloading not working properly
- Losing the Navigator state when updating values in some Inherited Widgets
- etc…
But what is the cause of all of this? And how can we solve it?
The didUpdateWidget problem
Note: In this section I will take a closer look at how FutureBuilder works. If you’re not interested in this, you can skip to the solution.
If we take a closer look at the code of FutureBuilder, we find that it is a StatefulWidget. As we know, StatefulWidgets maintain a long-livedStateobject. This state has a few methods that manage its life-cycle, like initState, build, and didUpdateWidget. initState is called only once when the state object is first created, and build is called every time we need to build the widget to display, but what what about didUpdateWidget? This method is called whenever the widget attached to this State object changes. When the widget is rebuilt with new inputs, the old widget is disposed, and a new widget is created and assigned to the State object, and didUpdateWidget is called to do anything we want to do before the rebuild. In case of FutureBuilder, this method looks like this:
@override
void didUpdateWidget(FutureBuilder<T> oldWidget) {
super.didUpdateWidget(oldWidget);
if (oldWidget.future != widget.future) {
if (_activeCallbackIdentity != null) {
_unsubscribe();
_snapshot = _snapshot.inState(ConnectionState.none);
}
_subscribe();
}
}
It’s basically saying: if, when rebuilt, the new widget has a different Future instance than the old one, then repeat everything: unsubscribe, and subscribe again.
Well, that’s the key! If we provide it with the same future, then it will not refire!
But aren’t we providing the same future? we’re calling the same function! well, it’s not the same future instance. Our function is doing exactly the same work, but then returning a new future, different from the old one.
So, what we want to do is to store or cache the output of the function the first time it is called, and then provide this same output whenever the function is called again. This process is known as memoization.
Solution: Memoize the future
Memoization is, in simple terms, caching the return value of a function, and reusing it when that function is called again. Memoization is mostly used in functional languages, where functions are deterministic (they always return the same output for the same inputs), but we can use simple memoization for our problem here, to make sure the FutureBuilder always receives the same future instance.
To do that, we will use Dart’s AsyncMemoizer. This memoizer does exactly what we want! It takes an asynchronous function, calls it the first time it is called, and caches its result. For all subsequent calls to the function, the memoizer returns the same previously calculated future.
Thus, to solve our problem, we start by creating an instance of AsyncMemoizerin our widget:
final AsyncMemoizer _memoizer = AsyncMemoizer();
Note: you shouldn’t instantiate the memoizer inside a StatelessWidget, because Flutter disposes of StatelessWidgets at every rebuild, which basically beats the purpose. You should instantiate it either in a StatefulWidget, or somewhere where it can persist.
Afterwards, we will modify our _fetchData function to use that memoizer:
_fetchData() {
return this._memoizer.runOnce(() async {
await Future.delayed(Duration(seconds: 2));
return 'REMOTE DATA';
});
}
- We wrapped our function with
AsyncMemoizer.runOncewhich does exactly what it sounds like; it runs the function only once, and when called again, returns the cached future.
And that’s it! Our FutureBuilder now only fires the first time around:

Thus, our FutureBuilder was getting confused, and thinking that a new future was passed to it, causing it to refire every time. To solve this, we used Dart’s AsyncMemoizer to pass the same future instance every time.
I hope this has been helpful! Let me know what you think!
textfield reload issue and other things reload problem.===================================的更多相关文章
- eclipse 打开是报错"reload maven project has encountered a problem"
不需要删除整个 .metadata 如果删除这个代价是重新导入全部项目 D:\eclipse-workspace\.metadata\.plugins\org.eclipse.e4.workbench ...
- 在IE浏览器中执行OpenFlashChart的reload方法时无法刷新的解决方法
由于项目需求,需要在网页上利用图表展示相关数据的统计信息,采用了OpenFlashChart技术.OpenFlashChart是一款开源的以Flash和Javascript为技术基础的免费图表,用它能 ...
- javascript 中的location.reload
location.reload()是什么意思 location.reload() 括号内有一个参数 true/false , 为空和false的效果一样. 如果该方法没有规定参数,或者参数是 fals ...
- 把Nginx加入系统服务 service nginx (start | stop | restart | reload)
vim /etc/init.d/nginx 1 #!/bin/bash 2 # nginx Startup script for the Nginx HTTP Server 3 # it is v ...
- 使用Tomcat的Reload提高开发速度(翻译)
欢迎转载http://www.cnblogs.com/coodream2009,有翻译的不太准确的地方请大家指出,我继续修改完善. 按照Java Servlet规范第四部分推荐的,Tomcat系统的实 ...
- layui table数据表格reload where参数保留问题
layui table数据表格reload where参数保留问题 在使用layui过程中多多少少会遇到些问题 table reload 有个坑:reload时where参数会保留上次的参数,如果用 ...
- javascript:location.reload()和location.replace()的区别,及对图片缓存的影响。
有段时间没有清理IE的临时文件(缓存文件),在我清理的时候,我突然发现一个问题. 我打开的一个网站,图片默认缓存一个月的,但我发现,当我上传图片或删除图片之后,图片重新缓存,也就意味着,在我上传新图片 ...
- Python中的reload函数
Python中的import语句可以导入module文件,但是import语句只是第一次导入的时候会执行module文件中的代码,然后就会把导入的模块文件存入到内存,当再次导入的时候,Python是直 ...
- python之reload用法
一.python2和python3的区别 python2中可以直接使用reload().python3中需要从库中导入,有两种方法: >>> from imp import relo ...
随机推荐
- javascript的数组之join()
join()方法将一个数组(或一个类数组对象)的所有元素根据传入的参数连接成一个字符串,并返回这个字符串. var elements = ['Fire', 'Wind', 'Rain']; conso ...
- Nginx基本安装
Windows安装Nginx 解压:nginx-windows 双击: nginx.exe 能看到nginx欢迎界面说明,nginx安装成功 演示下 nginx做静态服务器 启动Nginx C:\se ...
- px,em,rem的区别与用法
别人总结的.个人觉得特别的好: http://www.w3cplus.com/css/when-to-use-em-vs-rem.html
- Python 学习笔记6 变量-字典
字典是python中一个十分重要的变量,他是一个可变的容器对象.通过一组key(键)和value(值)对组成一个元素. 组成形式为{'key':'value', 'key':'value'}.整个字典 ...
- 理解es6 中 arrow function的this
箭头函数相当于定义时候,普通函数.bind(this)箭头函数根本没有自己的this,导致内部的this就是定义时候的外层代码块中的this.外层代码块中的this,则取决于执行时候环境上下文cont ...
- Linux升级python3之后yum不能正常使用解决方法一:重新配置yum源
[转]linux下yum安装及配置 分步阅读 公司使用的是linux搭建服务器,linux安装软件能够使用yum安装依赖包是一件非常简单而幸福的事情,所以这里简单介绍一下linux安装yum源流程和操 ...
- Spring Boot 国际化及点击链接跳转国家语言
一.国际化 在SpringBoot中已经自动帮我们配置管理国际化资源的组件,所以我们只需要编写代码就可. @Bean @ConfigurationProperties(prefix = "s ...
- 3n+1猜想——模拟
package dxb.com; import java.util.Scanner; public class caixiang { public static void main(String[] ...
- java-concurrent包
通常所说的concurrent包基本有3个package组成 java.util.concurrent:提供大部分关于并发的接口和类,如BlockingQueue,Callable,Concurren ...
- FPC全制造组装的流程介绍(转载)
[维文信FPC]FPC又称柔性电路板,FPC的PCBA组装焊接流程与硬性电路板的组装有很大的不同,因为FPC板子的硬度不够,较柔软,如果不使用专用载板,就无法完成固定和传输,也就无法完成印刷.贴片.过 ...