【问题标题】:how to auto refresh component when redux state get updated如何在 redux 状态更新时自动刷新组件
【发布时间】:2021-11-27 12:33:36
【问题描述】:

我目前将用户名存储在 redux 商店中,并在用户登录后将其显示在顶部栏中。(在屏幕截图中显示)。但是,当 redux 状态更新时,它不会自动重新渲染。我仍然需要在顶部栏中执行一些操作,然后才会出现用户名。否则,它不会出现。所以问题是,如何强制从我的登录组件重新渲染顶部栏组件。 另一个问题:刷新页面时用户名会消失。那么有没有办法用 redux 状态来持久化数据呢?或者这是不可能的。

const Login = () => {
  ...
  const handleLogin = async googleData => {
    ...
    //store user name value als application state into redux store
    store.dispatch(nameActionCreator(googleData.profileObj.name));
    ...
  }
}

const TopBar = () => {
  ...
  return(
    ...
    <h5>store.getState().userNameRecuder.name</h5>
    ...
  )
}

登录前

登录后

【问题讨论】:

    标签: reactjs redux rerender


    【解决方案1】:

    第一个问题

    简答:

    您必须使用useSelector 挂钩调用选择器函数。您直接在 &lt;h5&gt; 元素中调用它。所以它不起作用。

    const TopBar = () => {
      const username = useSelector(() => store.getState().userNameRecuder.name)
    
      return(
        <h5>{username}</h5>
      )
    }
    
    最佳实践的长答案:

    您需要创建一个selector 并在您的组件中使用它来在状态更改后重新渲染您的组件。

    在 selector.js 中

    const selectUsername = (state) => state.userNameRecuder.name
    
    export selectUsername;
    

    现在,在您的 Topbar 组件中,您需要实现 useSelector 挂钩:

    import {useSelector} from 'react-redux';
    import {selectUsername} from 'store/selectors';
    
    function TopBar () {
      
      const username = useSelector(selectUsername)
    
      return (
        <p>username</p>
      )
    }
    
    

    使用适当的操作更新状态(更新用户名)将导致 Topbar 组件重新渲染以从商店获取新用户名。

    第二个问题

    有很多很好的方法可以持久化数据,例如将它们存储在cookieslocalStorage 或使用第三方库(如redux-persist)等等... 看看this post

    【讨论】:

      【解决方案2】:

      它基于@novonimo 的回答工作。即使没有分开 selector.js。只需使用useSelector钩子将redux状态与组件的状态连接起来,当redux状态发生变化时,组件会自动重新渲染。

      const TopBar = () => {
            const userName = useSelector(() => store.getState().userNameRecuder.name);
            
            return(
              ...
              <h5>userName</h5>
              ...
            )
          }

      【讨论】:

      • 感谢您的好回答,实际上“() => store.getState().userNameRecuder.name”是选择器,但在您的 useSelector 挂钩中隐含定义。分离选择器将有助于更改存储对象或进行调试