As far as I understood, calling 'setState()' inside a state doesn't make the state's didUpdateWidget() get called.

However, if the widget returned by this state in the 'build()' method is a StatefulWidget(or if there's any StatefulWidgets down the tree from this point), then 'didUpdateWidget()' in the States of those StatefulWidgets would be called.

To understand the reason, we could take a look at flutter's source code in framework.dart, and here's a rough summary of the code flow when calling 'setState()' in a State:

stateA(say) calls 'setState()' In 'setState()', it calls "_element.markNeedsBuild()", which adds '_element' to the list of dirty elements who would be re-built later on by flutter( '_element' is simply the element object that StateA is binded to, for convenience let's name it elementA) In the next frame flutter would go through the list of dirty elements, and for each element 'element', flutter calls element.rebuild(), so elementA.rebuild() would be called in the loop. In elementA.rebuild(), it eventually calls "built = stateA.build()", then "updateChild(_child, built)" (where _child is elementA's next element down the tree, which this 'built' widget is binded to). updateChild(_child, built) sets widget 'built' as the binded widget of element '_child', thus here is where the 'change of configuration of an element' happens, and hence calling 'didUpdateWidget()' inside element '_child'(if it is a StatefulElement)

For 'didUpdateWidget()', the flutter docs says that it is "Called whenever the widget configuration changes" And the key idea is that 'setState()' in stateA does not rebuild widgetA, but rebuilds the widget returned by stateA. Therefore, the 'change of configuration' happens to the returned widget, whilst widgetA remains the same.