title: Custom hook with useRef and useEffect
body: <p>I was reading a blog post which uses custom hooks and d3.
  It consists of following code:</p>
  <p>BarChart.js:</p>
  <pre><code>    import { useD3 } from './hooks/useD3';
      import React from 'react';
      import * as d3 from 'd3';
  
      function BarChart({ data }) {
        const ref = useD3(
          (svg) =&gt; {
  
  
            // console.log(svg)
            const height = 500;
            const width = 500;
            const margin = { top: 20, right: 30, bottom: 30, left: 40 };
  
            const x = d3
              .scaleBand()
              .domain(data.map((d) =&gt; d.year))
              .rangeRound([margin.left, width - margin.right])
              .padding(0.1);
  
            const y1 = d3
              .scaleLinear()
              .domain([0, d3.max(data, (d) =&gt; d.sales)])
              .rangeRound([height - margin.bottom, margin.top]);
  
            const xAxis = (g) =&gt;
              g.attr(&quot;transform&quot;, `translate(0,${height - margin.bottom})`).call(
                d3
                  .axisBottom(x)
                  .tickValues(
                    d3
                      .ticks(...d3.extent(x.domain()), width / 40)
                      .filter((v) =&gt; x(v) !== undefined)
                  )
                  .tickSizeOuter(0)
              );
  
            const y1Axis = (g) =&gt;
              g
                .attr(&quot;transform&quot;, `translate(${margin.left},0)`)
                .style(&quot;color&quot;, &quot;steelblue&quot;)
                .call(d3.axisLeft(y1).ticks(null, &quot;s&quot;))
                .call((g) =&gt; g.select(&quot;.domain&quot;).remove())
                .call((g) =&gt;
                  g
                    .append(&quot;text&quot;)
                    .attr(&quot;x&quot;, -margin.left)
                    .attr(&quot;y&quot;, 10)
                    .attr(&quot;fill&quot;, &quot;currentColor&quot;)
                    .attr(&quot;text-anchor&quot;, &quot;start&quot;)
                    .text(data.y1)
                );
  
            svg.select(&quot;.x-axis&quot;).call(xAxis);
            svg.select(&quot;.y-axis&quot;).call(y1Axis);
  
            svg
              .select(&quot;.plot-area&quot;)
              .attr(&quot;fill&quot;, &quot;steelblue&quot;)
              .selectAll(&quot;.bar&quot;)
              .data(data)
              .join(&quot;rect&quot;)
              .attr(&quot;class&quot;, &quot;bar&quot;)
              .attr(&quot;x&quot;, (d) =&gt; x(d.year))
              .attr(&quot;width&quot;, x.bandwidth())
              .attr(&quot;y&quot;, (d) =&gt; y1(d.sales))
              .attr(&quot;height&quot;, (d) =&gt; y1(0) - y1(d.sales));
          },
          [data.length]
        );
        console.log(&quot;before svg render &quot;,ref)
        return (
          &lt;svg
            ref={ref}
            style={{
              height: 500,
              width: &quot;100%&quot;,
              marginRight: &quot;0px&quot;,
              marginLeft: &quot;0px&quot;,
            }}
          &gt;
            &lt;g className=&quot;plot-area&quot; /&gt;
            &lt;g className=&quot;x-axis&quot; /&gt;
            &lt;g className=&quot;y-axis&quot; /&gt;
          &lt;/svg&gt;
        );
      }
  
      export default BarChart;
  </code></pre>
  <p>useD3.js hook:</p>
  <pre><code>    import React from 'react';
      import * as d3 from 'd3';
  
      export const useD3 = (renderChartFn, dependencies) =&gt; {
          const ref = React.useRef();
  
          React.useEffect(() =&gt; {
              renderChartFn(d3.select(ref.current));
              return () =&gt; {};
            }, dependencies);
          return ref;
      }
  </code></pre>
  <p>App.js:</p>
  <pre><code>    import React from 'react';
      import BarChart from './BarChart';
      import './App.css';
  
      const data = [
        {year: 1980, efficiency: 24.3, sales: 8949000},
        {year: 1985, efficiency: 27.6, sales: 10979000},
        {year: 1990, efficiency: 28, sales: 9303000},
        {year: 1991, efficiency: 28.4, sales: 8185000},
        {year: 1992, efficiency: 27.9, sales: 8213000},
        {year: 1993, efficiency: 28.4, sales: 8518000},
        {year: 1994, efficiency: 28.3, sales: 8991000},
        {year: 1995, efficiency: 28.6, sales: 8620000},
        {year: 1996, efficiency: 28.5, sales: 8479000},
        {year: 1997, efficiency: 28.7, sales: 8217000},
        {year: 1998, efficiency: 28.8, sales: 8085000},
        {year: 1999, efficiency: 28.3, sales: 8638000},
        {year: 2000, efficiency: 28.5, sales: 8778000},
        {year: 2001, efficiency: 28.8, sales: 8352000},
        {year: 2002, efficiency: 29, sales: 8042000},
        {year: 2003, efficiency: 29.5, sales: 7556000},
        {year: 2004, efficiency: 29.5, sales: 7483000},
        {year: 2005, efficiency: 30.3, sales: 7660000},
        {year: 2006, efficiency: 30.1, sales: 7762000},
        {year: 2007, efficiency: 31.2, sales: 7562000},
        {year: 2008, efficiency: 31.5, sales: 6769000},
        {year: 2009, efficiency: 32.9, sales: 5402000},
        {year: 2010, efficiency: 33.9, sales: 5636000},
        {year: 2011, efficiency: 33.1, sales: 6093000},
        {year: 2012, efficiency: 35.3, sales: 7245000},
        {year: 2013, efficiency: 36.4, sales: 7586000},
        {year: 2014, efficiency: 36.5, sales: 7708000},
        {year: 2015, efficiency: 37.2, sales: 7517000},
        {year: 2016, efficiency: 37.7, sales: 6873000},
        {year: 2017, efficiency: 39.4, sales: 6081000},
      ]
  
      function App() {
        return (
          &lt;div className=&quot;App&quot;&gt;
            &lt;header className=&quot;App-header&quot;&gt;
              &lt;BarChart data={data} /&gt;
            &lt;/header&gt;
          &lt;/div&gt;
        );
      }
  
      export default App;
  </code></pre>
  <p>When BarChart runs, it calls useD3 hook before its render method. Inside useD3 hook, code runs and after the return ref; line, the callback of the useEffect hook should run. This is my thought process, but apparently react doesnt work like that. Can someone enlighten me?
  When exactly does the useEffect callback run?</p>