Flutter 在颤振中使用提供程序时,如何避免不必要的重建?
我正在我的应用程序中使用,但我面临着不必要的构建 范例Flutter 在颤振中使用提供程序时,如何避免不必要的重建?,flutter,dart,provider,Flutter,Dart,Provider,我正在我的应用程序中使用,但我面临着不必要的构建 范例 class AllWidget extends StatelessWidget{ @override Widget build(BuildContext context){ print('state build called'); return ChangeNotifierProvider( builder: (_) => MyCounter(), child:
class AllWidget extends StatelessWidget{
@override
Widget build(BuildContext context){
print('state build called');
return ChangeNotifierProvider(
builder: (_) => MyCounter(),
child: Column(children: <Widget>[
MyCounterText(),
MyIncreaseButton(),
MyDecreaseButton(),
],
),
);
}
}
class MyCounterText extends StatelessWidget{
@override
Widget build(BuildContext context) {
final myCounter = Provider.of<MyCounter>(context, listen: false);
print('MyCounterText');
return Text(myCounter.num.toString());
}
}
class MyIncreaseButton extends StatelessWidget{
@override
Widget build(BuildContext context) {
final myCounter = Provider.of<MyCounter>(context, listen: false);
print('MyIncreaseButton');
return RaisedButton(
child: Text('Increase +'),
onPressed: ()=> myCounter.increament(),
);
}
}
class MyDecreaseButton extends StatelessWidget{
@override
Widget build(BuildContext context) {
final myCounter = Provider.of<MyCounter>(context, listen: false);
print('MyDecreaseButton');
return RaisedButton(
child: Text('Decrease -'),
onPressed: ()=> myCounter.decreament(),
);
}
}
class AllWidget扩展了无状态widget{
@凌驾
小部件构建(构建上下文){
打印('state build called');
返回ChangeNotifierProvider(
生成器:(\u)=>MyCounter(),
子项:列(子项:[
MyCounterText(),
MyIncreaseButton(),
MyDecreaseButton(),
],
),
);
}
}
类MyCounterText扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
final myCounter=Provider.of(context,listen:false);
打印('MyCounterText');
返回文本(myCounter.num.toString());
}
}
类MyIncreaseButton扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
final myCounter=Provider.of(context,listen:false);
打印(“MyIncreaseButton”);
返回上升按钮(
子项:文本('增加+'),
onPressed:()=>myCounter.increment(),
);
}
}
类MyDecreaseButton扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
final myCounter=Provider.of(context,listen:false);
打印(“MyDecreaseButton”);
返回上升按钮(
子项:文本('减少-'),
按下时:()=>myCounter.decreament(),
);
}
}
现在,如果我点击MyIncreaseButton
小部件来增加值,MyDecreaseButton
小部件也会生成,即使我没有点击它
反之亦然,如果我点击MyDecreaseButton
widget来减少值,那么myEncreaseButton
widget也会生成,即使我没有点击它
我的期望是:
单击
MyIncreaseButton
小部件时,不应构建MyDecreaseBtton
小部件。有多种解决方案:
- 使用
上下文。阅读
或将
传递给侦听:false
:提供者。of
RaisedButton(
已按下:(){
context.read().increment();
//或者,请:
Provider.of(context,listen:false).increment();
},
child:child(),
);
- 使用
上下文。选择
:
- 使用
:选择器
选择器就是您所需要的。使用选择器,您可以筛选更新。 例如,要仅在名称更改时更新,可以执行以下操作
Selector<AppStore, String>(
selector: (_, store) => store.name,
builder: (_, name, __) {
return Text(name);
},
);
选择器(
选择器:(_,store)=>store.name,
建筑商:(uu,名称,uuu){
返回文本(名称);
},
);
我只是通过如下编辑代码来避免不必要的渲染:
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:flutter/foundation.dart';
class MyCounter with ChangeNotifier {
int _num = 0;
int get num => _num;
set num(int n) {
_num = n;
notifyListeners();
}
void increament() {
_num = _num + 1;
notifyListeners();
}
void decreament() {
_num = _num - 1;
notifyListeners();
}
}
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
print('root build called');
return ChangeNotifierProvider(
builder: (context) => MyCounter(),
child: MaterialApp(
title: 'MyAppJan',
home: Scaffold(
appBar: AppBar(title: Text('Home')),
body: AllWidget(),
),
theme: ThemeData(primarySwatch: Colors.orange),
));
}
}
class AllWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
print('state build called');
return Center(
child: Column(
children: <Widget>[
MyCounterText(),
SizedBox(height: 10),
MyIncreaseButton(),
SizedBox(height: 10),
MyDecreaseButton(),
],
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
),
);
}
}
class MyCounterText extends StatelessWidget {
@override
Widget build(BuildContext context) {
print('MyCounterText');
return Consumer<MyCounter>(
builder: (context, myCounter, _) {
return Text(myCounter.num.toString());
},
);
}
}
class MyIncreaseButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
final _items = Provider.of<MyCounter>(context,listen: false);
print('MyIncreaseButton');
return RaisedButton(
child: Text('Increase ++'),
onPressed: () => _items.increament(),
);
}
}
class MyDecreaseButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
final _items = Provider.of<MyCounter>(context,listen: false);
print('MyDecreaseButton');
return RaisedButton(
child: Text('Decrease --'),
onPressed: () => _items.decreament(),
);
}
}
导入“包装:颤振/材料.省道”;
导入“包:provider/provider.dart”;
进口“包装:颤振/基础.dart”;
使用ChangeNotifier类MyCounter{
int _num=0;
int get num=>\u num;
set num(int n){
_num=n;
notifyListeners();
}
无效增量(){
_num=_num+1;
notifyListeners();
}
void decreament(){
_num=_num-1;
notifyListeners();
}
}
void main(){
runApp(MyApp());
}
类MyApp扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
打印('root-buildcalled');
返回ChangeNotifierProvider(
生成器:(上下文)=>MyCounter(),
孩子:MaterialApp(
标题:“MyAppJan”,
家:脚手架(
appBar:appBar(标题:Text('Home')),
正文:AllWidget(),
),
主题:主题数据(原始样本:颜色。橙色),
));
}
}
类AllWidget扩展了无状态Widget{
@凌驾
小部件构建(构建上下文){
打印('state build called');
返回中心(
子:列(
儿童:[
MyCounterText(),
尺寸箱(高度:10),
MyIncreaseButton(),
尺寸箱(高度:10),
MyDecreaseButton(),
],
mainAxisAlignment:mainAxisAlignment.center,
mainAxisSize:mainAxisSize.min,
),
);
}
}
类MyCounterText扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
打印('MyCounterText');
退货消费者(
生成器:(上下文,myCounter,389;){
返回文本(myCounter.num.toString());
},
);
}
}
类MyIncreaseButton扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
final _items=Provider.of(上下文,侦听:false);
打印(“MyIncreaseButton”);
返回上升按钮(
子项:文本('Increase++'),
按下时:()=>\u items.increment(),
);
}
}
类MyDecreaseButton扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
final _items=Provider.of(上下文,侦听:false);
打印(“MyDecreaseButton”);
返回上升按钮(
子项:文本('减少--'),
按下时:()=>_items.decreament(),
);
}
}
您的示例不清楚。你能找出一些实际运行的问题吗?@RémiRousselet,你好,谢谢你,请再看看我编辑的问题。如您所见,我有树状小部件,我想要更新widget2,因此只有这个小部件应该是build(render)而不是widget1和widget3,如果您使用了react native
有一个名为shouldcomponentupdate(np,ns)
的生命周期函数,它让我们避免不属于它的不必要的渲染。 为什么我担心一个大的列表,其中的每一项都是一个小部件,那么为什么我要问这个问题:我的ListView有1000项,我更新了