title: useSelector hook and rerenders
body: <p>-- edit -- i created a codesandbox: <a href="https://codesandbox.io/s/xenodochial-hofstadter-d3jjo" rel="noreferrer">https://codesandbox.io/s/xenodochial-hofstadter-d3jjo</a></p>
  
  <p>I'm starting to scratch my head and would like some help on - I assume - a simple problem.</p>
  
  <p>I have a basic App component that renders a controlled text input. Once you submit this input it creates a message on the back-end, which updates a redux store. Everything seems to be working fine on this part.</p>
  
  <p>My issue is when I tried to add a <code>useEffect</code> hook to reset the input value after a new message was added. I noticed that the <code>useEffect</code> that relies on <code>[messages]</code> is called on every render instead of just when <code>messages</code> changes. The simple act of typing in the input - which causes a rerender for every character - makes the hook trigger, even though it is still the same value: an empty array.</p>
  
  <p>Basically I've noticed it only works as intended if my <code>useSelector</code> returns the same instance of an array. So if I were to read only <code>state.messages.allIds</code> it would work since the array does not change. But simply adding a <code>.map(x =&gt; x)</code> makes it return a new instance every time.
  I have added react-redux's <code>shallowEqual</code> to try and fix this, but to no avail, and I don't understand why it doesn't fix my problem.</p>
  
  <pre><code>const App = () =&gt; {
    const [message, setMessage] = useState('');
    const messages = useSelector(
      (state: RootState) =&gt; (
        state.messages.allIds.map((id: string) =&gt; state.messages.byId[id])
      ),
      shallowEqual,
    );
  
    useEffect(() =&gt; {
      console.log('useEffect');
    }, [messages]);
  
    // ...
  
    return (
      &lt;form onSubmit={/* ... */}&gt;
        &lt;input
          onChange={event =&gt; setMessage(event.target.value)}
          value={message}
        /&gt;
      &lt;/form&gt;
    );
  }
  </code></pre>