useSelector钩子和渲染器

问题描述 投票:2回答:1

-编辑-我创建了一个codeandbox:https://codesandbox.io/s/xenodochial-hofstadter-d3jjo

我开始挠头,想要一些帮助-我想这是一个简单的问题。

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

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

基本上,我已经注意到,只有当我的useSelector返回数组的相同实例时,它才能按预期工作。因此,如果我只读state.messages.allIds,它将有效,因为数组不会更改。但是,只需添加.map(x => x)即可使其每次都返回一个新实例。我添加了react-redux的shallowEqual来尝试解决此问题,但无济于事,而且我不明白为什么它不能解决我的问题。

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>
  );
}
reactjs react-hooks
1个回答
2
投票

useMemo呢?

 const messages = useSelector(
    (state: RootState) => (
      state.messages
    ),
    shallowEqual,
  );

 let mapped  = useMemo(() => messages.allIds.map((id: string) => messages.byId[id]), [messages]);

现在随处使用mapped。虽然不熟悉打字稿,但是您知道了。

© www.soinside.com 2019 - 2024. All rights reserved.