title: The correct way to play animation when parent state changes
body: <p>I have a <code>Navigation</code> widget which owns the state of the current navigation context: the index of the tab which is shown at the moment. <code>Navigation</code> renders a set of navigation items <code>NavigationItem</code> each representing a tab from a certain number of different tabs. When a <code>NavigationItem</code> is clicked, I want to navigate to the corresponding tab within that number of tabs and play the animation.</p>
  <pre><code>class _NavigationState extends State&lt;Navigation&gt; {
    int currentPage = 0;
  
    void setPage(int page) {
      final newPage = max(0, min(widget.pages.length - 1, page));
  
      setState(() {
        currentPage = newPage;
      });
    }
  
    @override
    void initState() {
      super.initState();
    }
  
    @override
    Widget build(BuildContext context) {
      final theme = ThemeProvider.of(context);
      final tabController = DefaultTabController.of(context);
  
      final navs = widget.pages.asMap().map((index, page) =&gt; MapEntry(
        index, 
        NavigationItem(
          selected: index == currentPage,
          onTap: () {
            setPage(index);
            tabController!.animateTo(index);
          },
      ))).values.toList();
      
      return Material(
        color: theme.background,
        child: Stack(
          children: [
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                ...navs
              ],
            ),
          ]
        ),
      );
    }
  }
  </code></pre>
  <p>Here, <code>currentPage</code> is the index within the tabs, and it changes each time I click on a <code>NavigationItem</code>. In each <code>NavigationItem</code> I pass the <code>selected</code> property which represents the state of a particular <code>NavigationItem</code>. Then, inside a <code>NavigationItem</code> I want to animate to the selected state (the same <code>NavigationItem</code> but bigger):</p>
  <pre><code>class _NavigationItemState extends State&lt;NavigationItem&gt; with SingleTickerProviderStateMixin  {
    late AnimationController controller;
    late Animation&lt;double&gt; animation;
  
    @override
    void initState() {
      super.initState();
  
      controller = AnimationController(duration: const Duration(milliseconds: 500), vsync: this);
  
      animation = Tween&lt;double&gt;(begin: 25, end: 50).animate(CurvedAnimation(parent: controller, curve: Curves.ease))
        ..addListener(() {
          setState(() {});
        });
    }
  
    @override
    void dispose() {
      controller.dispose();
      
      super.dispose();
    }
  
    @override
    Widget build(BuildContext context) {
      // if (widget.selected) {
      //   controller.forward();
      // } else {
      //   controller.reverse();
      // }
  
      return GestureDetector(
        onTap: widget.onTap,
        child: Container(
          width: animation.value,
          height: animation.value,
          decoration: const BoxDecoration(
            color: Colors.red,
            shape: BoxShape.circle
          ),
        ),
      );
    }
  }
  </code></pre>
  <p>Now, I'm confused about where I should the animation logic depending on the passed properties. Putting it in the <code>build</code> method seems to work, however I'm not sure whether it is the correct way for a child to react to its changed configuration coming from its parent.</p>
  <p>Note that I've omitted the code for each corresponding stateful widget to keep this example as short as possible.</p>