title: Is it safe to run animations in a useEffect hook?
body: <p>I've started introducing some React hooks into my code, specifically the <code>useEffect</code> and I can't seem to find out whether what I'm doing is considered safe or not. Essentially I'm running animations on the DOM within the hook, and I want to ensure that's not going to break any DOM snapshots for example.</p>
  
  <p>Here's an example, I've modified from my full example to try and be concise to illustrate what's happening:</p>
  
  <pre><code>export function GrowingCircle(props) {
  
    const root = useRef(null);          // This is the root element we draw to
  
    // The actual rendering is done whenever the data changes
    useEffect(() =&gt; {
  
      const radius = props.width / 2;
  
      d3.select(root.current)
        .transition()
        .duration(1000)
        .attr("r", radius);
  
    }, [props.width]);
  
    return (
        &lt;svg width={props.width} height="100%"&gt;
          &lt;circle ref={root} cx="0" cy="0" r="0" fill="red" /&gt;
        &lt;/svg&gt;
      );
  }
  </code></pre>
  
  <p>The part I'm concerned about is the <code>.transition()</code> is going to run frequent updates on the DOM for 1 second, and I'm unsure if that's going to mess up the react rendering?</p>
  
  <hr>
  
  <p>A follow up question (as often we don't have control of the animation rendering like in this example). Would the following where the <code>circle</code> is no longer within the JSX change things?</p>
  
  <pre><code>export function GrowingCircle(props) {
  
    const root = useRef(null);          // This is the root element we draw to
  
    // The actual rendering is done whenever the data changes
    useEffect(() =&gt; {
  
      const radius = props.width / 2;
  
      d3.select(root.current)
        .append("circle")
        .attr("cx", 0)
        .attr("cy", 0)
        .attr("fill", "red")
        .transition()
        .duration(1000)
        .attr("r", radius);
  
    }, [props.width]);
  
    return (
        &lt;svg ref={root} width={props.width} height="100%"&gt;
        &lt;/svg&gt;
      );
  }
  </code></pre>