0

我想创建一些中间件来检查令牌 expires_at 字段,如有必要,刷新令牌并更新令牌字段的状态。

我使用了 redux 工具包来创建 redux 功能,并使用了切片。我有一个切片,它将使用令牌数据更新状态,这适用于初始令牌的回调。

创建中间件时,我无法调用切片,因此状态保持不变。

作为没有 api 调用的简单峰值:

import { useSelector, useDispatch } from 'react-redux';
import { setTokens } from '../features/tokens/tokenSlice';

const refresher = () => ({ dispatch, getState }) => (next) => (action) => {
    const exp_at = useSelector((state) => state.tokens.expires_at);

    if(hasBreachedThreshold(exp_at)){
        dispatch = useDispatch();
        dispatch(
            setTokens({
            access_token: 'new token',
            expires_at: 637423776000000000, -- hard coded date way in the future.
        })
    }
    
    ... else carry on.
);

我希望在调用中间件时,第一遍 hasBreachedThreshold() 返回 true,并且调度方法将调用切片缩减器并更新状态。任何进一步的运行都会过去,因为 hasBreachedThreshold() 将返回 false - 无论如何都会有一段时间。

但发生的情况是 hasBreachThreshold 总是返回 false,因为状态永远不会更新,从而导致无限循环。

中间件配置正确并被调用。expires_at 值是从状态中提取的。hasBreachThreshold() 已经过彻底测试并且行为正确。

作为 React / Redux 的新手,我希望我对如何以及何时使用 dispatch 的理解是错误的。我以为我可以像在组件中那样使用调度,不是这样吗?还是我要这样做完全错误的方式?

4

1 回答 1

1

在编写中间件时,您已经通过函数 params 获得dispatch了函数和 Redux 存储:

// Use `dispatch` & `getState`
const refresher = () => ({ dispatch, getState }) => (next) => (action) => {
    const exp_at = getState().tokens.expires_at;

    if(hasBreachedThreshold(exp_at)){
        dispatch(
            setTokens({
            access_token: 'new token',
            expires_at: 637423776000000000, -- hard coded date way in the future.
        })
    }
);

此外,您对何时使用 React hooks 有基本错误,请参阅Rules of Hooks

Hooks 在 Redux 中间件的上下文中不可用。

于 2020-08-23T11:37:02.853 回答