Provider automatically gets updated when calling setState

Viewed 321

I am new to Flutter and currently working with Providers. I am pulling some static array list from an api and saving it to the Provider. I am letting the user to select from this list and attach to the Item he is creating using the form.

So, Everytime the user tries to create a new Item, he/she should see the static list with the selection set to false.

But, the provider array variable gets automatically updated upon calling setState. Below is the Issue I'm facing..

main.dart

MultiProvider(
      providers: [
        ChangeNotifierProvider<Info1Class>(
          create: (ctx) => Info1Class(),
        ),
        ChangeNotifierProvider<Info2Class>(
          create: (ctx) => Info1Class(),
        ),
      ],
      child: MaterialApp(

And in my Stateful widget in the build method. I am getting the Provider Details like this.

screenArray.clear();
    final t = Provider.of<Info1Class>(context, listen: false).dataArray;
    screenArray.addAll(t);

Whenever I call setState to update the elements of screenArray, the provider data gets updated as well.

setState(() {screenArray[0].selected = true})

After setState(), if I print the Provider dataArray's first element, it showing as true.

print(Provider.of<Info1Class>(context, listen: false).dataArray[0].selected)

My Dependancies

provider: ^4.3.2+4

Is there a way to avoid the Provider data getting updated and only update the variable in my Stateful Widget ?

Please let me know if I am missing something.. Thanks for your help.

1 Answers

I tried Getx and Provider both for this problem, it's problem of referencing of object not the Provider or GetX, I was coping reference of Objects, list or all data. to Solve this problem, I create clone of each object and then use it.

  // COMMON
  String? uid;
  String? username;
  String? fullName;
  String? email;
  num? timestamp;
  List<ProfilePhoto>? photos;
  List<String>? skills;
  

I add one object list and other simple String list Clone class

MyUser.clone(MyUser? myUser) {
        uid = myUser?.uid;
        username = myUser?.username;
        fullName = myUser?.fullName;
        userType = myUser?.userType;
        email = myUser?.email;
        timestamp = myUser?.timestamp;
        photos = ProfilePhoto.cloneList(myUser?.photos);
        status = myUser?.status;
        skills = [...(myUser?.skills ?? [])];
       
      }

Constructor

MyUser({
     this.uid,
     this.username,
     this.fullName,
     this.email,
     this.timestamp,
     this.photos,
     this.skills,)};

Photo class

class ProfilePhoto {
  String? id;
  String? title;
  String? url;
  File? file;
  bool? isDefault;



  ProfilePhoto({
    this.id,
    this.title,
    this.url,
    this.file,
    this.isDefault,
  });

  ProfilePhoto.clone(ProfilePhoto profilePhoto) {
    id = profilePhoto.id;
    title = profilePhoto.title;
    url = profilePhoto.url;
    file = profilePhoto.file;
    isDefault = profilePhoto.isDefault;
  }
  static List<ProfilePhoto>? cloneList(List<ProfilePhoto>? items) {
    if (items == null) return [];
    List<ProfilePhoto>? newItems = [];
    for (ProfilePhoto item in items) {
      newItems.add(ProfilePhoto.clone(item));
    }
    return newItems;
  }
}

Screen layout

@override
void didChangeDependencies() {
  super.didChangeDependencies();
  final data = _userController.user;
  MyUser? user = MyUser.clone(data);
}

void _onChangeDefault(int index) {
    ProfilePhoto pp = _profilePhotos[index];
    setState(() {
      _profilePhotos.removeAt(index);
      _profilePhotos.insert(0, pp);
    });
  }

this may be not a good or optimized solution, but this solve my problem of auto update data in state manager

Related