如何避免由于 redux 状态的 redux store update/propagation 到连接组件的延迟而导致的重复操作分派?

How do I avoid duplicate action dispatches caused by to a delay in redux store update/propagation of redux state to connected components?

我正在开发一个使用 React-Router 和 Redux 的 React 应用程序。

这个应用程序有一些需要身份验证的路由,在这种情况下,我将用户重定向到登录页面,如下所示。

return <Redirect 
  to={{
    pathname: '/login',
    search: `?ret=${encodeURIComponent(location.pathname)}`
}}

登录页面使用登录组件呈现,该组件连接到 redux 存储并检查布尔值 isSignedIn。当 isSignedIn === true 时,我将用户重定向到 ret 查询参数中指定的路径。相关代码如下。

const Login = (props) => {
    if (!props.isSignedIn) {
        // show a message and CTA asking the user to log in
    }

    const queryParams =  qs.parse(props.location.search, { ignoreQueryPrefix: true });
    const ret = queryParams.ret || '/';
    
    return <Redirect to={ret} />
}

我在应用程序中使用 google oAuth2,在用户通过 Google 登录后,我发送一个 SIGN_IN 操作,将 isSignedIn 更新为 true。 oAuth 流程由 GoogleAuth 组件处理,该组件会在每次呈现页面时检查用户是否已登录,并且还会处理登录 in/sign 退出点击事件。此组件呈现在应用程序的每个页面上。

class GoogleAuth extends React.Component {
    componentDidMount() {
        window.gapi.load('client:auth2', () => {
            window.gapi.client.init({
                clientId: 'someclientid',
                scope: 'email'
            }).then(() => {
                this.auth = window.gapi.auth2.getAuthInstance();
                // initial check to see if user is signed in
                this.onAuthChange(this.auth.isSignedIn.get());
                // listens for change in google oAuth status
                this.auth.isSignedIn.listen(this.onAuthChange);
            })
        });
    };

    onAuthChange = async (isGoogleSignedIn) => {
        if (!this.props.isSignedIn && isGoogleSignedIn){
            await this.props.signIn(this.auth.currentUser.get().getId());
        } else if (this.props.isSignedIn && !isGoogleSignedIn) {
            await this.props.signOut();
        }
    }

    handleSignIn = () => {
        this.auth.signIn();
    }

    handleSignOut = () => {
        this.auth.signOut();
    }

我面临的问题是,当我从“/login”页面登录并重定向时,SIGN_IN 操作(通过调用 this.props.signIn() 调度)被多次调用.

重定向似乎发生在 redux 存储正确更新 isSignedIn 的值之前,这导致了重复的 SIGN_IN 动作调度。

我该如何防止这种情况发生?我考虑过在重定向之前添加一个短暂的延迟,但我不确定这是正确的方法。

编辑: 我发现发生这种情况是因为我在登录页面上渲染了两次 GoogleAuth 组件(一次在 header 中,一次在页面本身上)。这导致动作被分派两次。两个 GoogleAuth 组件都检测到身份验证状态的变化,因此都派发了 SIGN_IN 操作。至少在这种情况下,redux 存储数据到连接组件的传播没有延迟。

好的,明白了。

我在登录页面上渲染了两次 GoogleAuth 组件 - 一次在 header 中,一次在主要内容中。这就是该操作被分派两次的原因。

两个 GoogleAuth 组件都检测到身份验证状态的变化,因此都派发了 SIGN_IN 操作。