title: Change detection in React
body: <p>I'd like to perform a side-effect when some data changes, e.g.</p>
  <pre class="lang-js prettyprint-override"><code>const useSearchResults = () =&gt; {
    const location = useLocation();
    const [data, setData] = useState();
    useEffect(() =&gt; {
      Api.search(location.query.q).then(data =&gt; setData(data));
    }, [location.query.q]);
  
    // Compute some derived data from `data`.
    const searchResults =
      data &amp;&amp;
      data.map(item =&gt; ({
        id: item.id,
        name: `${item.firstName} ${item.lastName}`
      }));
  
    return searchResults;
  };
  
  const Component = () =&gt; {
    const searchResults = useSearchResults();
    useEffect(() =&gt; {
      alert('Search results have changed'); // Side-effect
    }, [searchResults]);
    return &lt;pre&gt;{JSON.stringify(searchResults)}&lt;/pre&gt;;
  };
  </code></pre>
  <p>If something causes <code>Component</code> to re-render, the <code>alert</code> will fire even if the <code>searchResults</code> haven't changed because we map over the underlying stable data in <code>useSearchResults</code> creating a new instance on every render.</p>
  <p>My initial approach would be to use <code>useMemo</code>:</p>
  <pre class="lang-js prettyprint-override"><code>  // Stabilise `searchResults`'s identity with useMemo.
    const searchResults = useMemo(
      () =&gt;
        data &amp;&amp;
        data.map(item =&gt; ({
          id: item.id,
          name: `${item.firstName} ${item.lastName}`
        })),
      [data]
    );
  </code></pre>
  <p>However <a href="https://reactjs.org/docs/hooks-reference.html#usememo" rel="nofollow noreferrer"><code>useMemo</code> has no semantic guarantee</a> so it's (theoretically) only good for performance optimisations.</p>
  <p>Does React offer a straight forward solution to this (common?) problem?</p>