2

I have a flutter app with redux state management. In my app, I want to refetch some data from server when some other data in other screen changed. But in my case, I navigate from screen1 to screen2, and some data chaned in screen 2. I use a boolean flag needUpdate saved to redux and set to true after changes on screen 2. But when I navigate back to screen1, I need to refetch data if the flag is true. But it did not work and data didnt refetch.

Here is some code:

class FirstScreen extends StatefulWidget {
  const FirstScreen({Key? key}) : super(key: key);

  @override
  State<StatefulWidget> createState() => _FirstScreenState();
}

class _FirstScreenState extends State<FirstScreen> {
  @override
  void initState() {
    super.initState();
  }

  @override
  void didChangeDependencies() async {
    final store = StoreProvider.of<AppState>(context);
    var needUpdate = store.state.commonState?.needUpdate.value ?? false;
    if (needUpdate) {
      await store.dispatch(prepareData(context));
    }
  }

  @override
  Widget build(BuildContext context) {}
}


class SecondScreen extends StatefulWidget {
  const SecondScreen({Key? key}) : super(key: key);

  @override
  State<SecondScreen> createState() => _SecondScreenState();
}

class _SecondScreenState extends State<SecondScreen> {
  @override
  void initState() {
    super.initState();
  }

  void onPress() async {
    await store.dispatch(ChangeNeedUpdatePortfolio(true));
    Navigator.pop(context);
  }

  @override
  Widget build(BuildContext context) {}
}

and Here is my action:

ThunkAction<AppState> updatePortfolioData(BuildContext context) {
  return (Store<AppState> store) async {
    bool needUpdate = store.state.commonState?.needUpdate.value ?? false;
    if (needUpdate) {
      ...
      await store.dispatch(ChangeNeedUpdatePortfolio(false));
      ...
      return;
    }
  };
}
Mohamadamin
  • 564
  • 5
  • 16

1 Answers1

0

You could try using the onInit property of the StoreConnector to load the initial data whenever the screen is displayed, like so:

return StoreConnector<AppState, void>(
      onInit: (store) {
        var needUpdate = store.state.commonState?.needUpdate.value ?? false;
        if (needUpdate) {
          await store.dispatch(prepareData(context));
        }
      }
      builder: (BuildContext context, data) {
      },
    );

And then for the screens you have two options.

Option 1: Use PushReplacement to navigate between these two screens. This will ensure that the data is updated because the onInit is called whenever the screen updates.

Option 2: Call a function from your first screen when you navigate back from the second screen.

return StoreConnector<AppState, void Function()>(
     converter: (store) { // This createds the function that you can call
        return () {
          var needUpdate = store.state.commonState?.needUpdate.value ?? false;
          if (needUpdate) {
            await store.dispatch(prepareData(context));
          }
        }
      },
      onInit: (store) {
        var needUpdate = store.state.commonState?.needUpdate.value ?? false;
        if (needUpdate) {
          await store.dispatch(prepareData(context));
        }
      }
      builder: (BuildContext context, updateData) {
         ...
         await Navigator.of(context)....
         updateData(); // Calls the function from your converter
         ...
      },
    );