useSelector 钩子和重新渲染

nse*_*ier 6 reactjs react-hooks

-- 编辑 -- 我创建了一个代码和框:https ://codesandbox.io/s/xenodochial-hofstadter-d3jjo

我开始摸不着头脑,想要一些帮助——我想——一个简单的问题。

我有一个呈现受控文本输入的基本 App 组件。提交此输入后,它会在后端创建一条消息,用于更新 redux 存储。这部分似乎一切正常。

我的问题是当我尝试添加一个useEffect挂钩以在添加新消息后重置输入值时。我注意到useEffect依赖的[messages]会在每次渲染时调用,而不仅仅是在messages更改时调用。输入输入的简单行为 - 这会导致每个字符的重新渲染 - 会触发钩子,即使它仍然是相同的值:一个空数组。

基本上我注意到它只有在我useSelector返回相同的数组实例时才能按预期工作。所以如果我只读取state.messages.allIds它会起作用,因为数组不会改变。但是简单地添加 a.map(x => x)使它每次都返回一个新实例。我已经添加了 react-reduxshallowEqual来尝试解决这个问题,但无济于事,我不明白为什么它不能解决我的问题。

const App = () => {
  const [message, setMessage] = useState('');
  const messages = useSelector(
    (state: RootState) => (
      state.messages.allIds.map((id: string) => state.messages.byId[id])
    ),
    shallowEqual,
  );

  useEffect(() => {
    console.log('useEffect');
  }, [messages]);

  // ...

  return (
    <form onSubmit={/* ... */}>
      <input
        onChange={event => setMessage(event.target.value)}
        value={message}
      />
    </form>
  );
}
Run Code Online (Sandbox Code Playgroud)

小智 1

这可能来得很晚。但这可能会让面临同样问题的其他人受益。

如果您不希望函数在状态更改时重新渲染,而只想提取 redux 状态变量的值,则可以使用 useState

const state = useState();
const yourVariable = state.getState().reduxStateVariable;
Run Code Online (Sandbox Code Playgroud)