Search code examples
flutterdartsetstatestatefulwidget

How setState call build in flutter?


I know build will be called everytime setState called and I want to find the method chain in the flutter framework.

So I check the source code of flutter and find some steps of setState:

  1. _element!.markNeedsBuild() mark state's element dirty. enter image description here enter image description here
  2. owner!.scheduleBuildFor(this) call BuildOwner's onBuildScheduled and add element to the dirty elements list. enter image description here
  3. BuildOwner's onBuildScheduled is assigned in WidgetsBinding's initInstances():enter image description here enter image description here enter image description here enter image description here enter image description here enter image description here
  4. And WidgetsBinding's initInstances() is called in runApp(). enter image description here enter image description here

I had check carefully but didn't see any code call state's build method.

How setState call build in flutter internal? Can we find any source code?


Solution

  • In handleDrawFrame() you see this part:

    try {
      // PERSISTENT FRAME CALLBACKS
      _schedulerPhase = SchedulerPhase.persistentCallbacks;
      for (final FrameCallback callback in _persistentCallbacks) {
        _invokeFrameCallback(callback, _currentFrameTimeStamp!);
      }
    

    I don't know exactly where it's added to the persistenCallbacks but looking at that variable in the code shows you

      /// The persistent callbacks (scheduled by
      /// [SchedulerBinding.addPersistentFrameCallback]) are currently executing.
      ///
      /// Typically, this is the build/layout/paint pipeline. See
      /// [WidgetsBinding.drawFrame] and [SchedulerBinding.handleDrawFrame].
      persistentCallbacks,
    

    Meaning it calls drawFrame

    Inside drawFrame you'll find this line:

        buildOwner!.buildScope(rootElement!);
    

    And inside this method it looks through all elements in _dirtyElements. Note that in scheduleBuildFor that you posted in this question it wass added to this. So in this buildScope it calls

    element.rebuild();
    

    This in turn calls

    performRebuild():
    

    which for ComponentElements says

      /// Calls the [StatelessWidget.build] method of the [StatelessWidget] object
      /// (for stateless widgets) or the [State.build] method of the [State] object
      /// (for stateful widgets) and then updates the widget tree.
      ///
      /// Called automatically during [mount] to generate the first build, and by
      /// [rebuild] when the element needs updating.
      @override
      @pragma('vm:notify-debugger-on-exception')
      void performRebuild() {