lodash throttle redux dispatch Uncaught TypeError:期望一个函数

时间:2018-02-02 20:35:26

标签: redux lodash dispatch throttling

TL; DR我在创建一个限制函数时遇到了奇怪的问题,我需要在创建限制函数时手动将参数传递给此方法。我可以通过改变原来的功能来做到这一点,但我不想为所有旧的遗产功能/动作创作者这样做。

传递给油门的功能:

注意: 这些是redux动作创建者。

const changeValue = (value: string, otherValue?: boolean) => {
    return {
        type: "SOME_TYPE",
        payload: {
            value: value,
            otherValue: otherValue || false
        }
    };
};

限制功能的创建:

const throttledMethod = (value: number, otherValue:boolean ) => {
    throttle(changeValue(Number(value),otherValue), 175, { "trailing": false });
};

这通常需要传递函数而不是调用, 但是除非我在调用,否则如何传递参数呢?我不想在这种情况下讨好。

产生错误:

node_modules\lodash\throttle.js:56 Uncaught TypeError: Expected a function
    at throttle (node_modules\lodash\throttle.js:56)

当break指向lodash中的第56行并检查时,我们看到从valueChanged返回的对象的值:

{
    type: "SOME_TYPE",
    payload: {
    value: value,
    otherValue: otherValue || false
}

这一切都很公平。

奇怪的是,我们通过在Redux动作创建器中执行一些相对较脏的手动工作来实现此功能。我称之为肮脏,因为我不想为我正在做的新事物改变所有旧的遗产行动创作者。

当我使用Redux.js调度方法手动包装我的动作创建器时,一切都按预期开始工作。:

const changeValue = (value: string, otherValue?: boolean) => {
    return function (dispatch) {
        dispatch({
            type: "SOME_TYPE",
            payload: {
                value: value,
                otherValue: otherValue || false
            }
        });
    };
};

所以最后这对Lodash来说真的不是一个问题,但是我们仍然可以解决如何正确地将参数传递给需要传递给限制的方法而不改变我原来的全部内容方法或currying。 Currying让很多人感到困惑,在某些情况下,我确实有点想要迎合不那么有文化的人。

也许我们可以创建一个包装器,在传递给lodash节流阀或其他方法时处理手动包装调度。我认为这样的事情是理想的,但无法想象这个包装器会是什么样子。

也许这是我可能会问作者的事情,但首先我想尝试" userland"。

1 个答案:

答案 0 :(得分:2)

首先,您可以通过将调用包装在匿名函数中来节省工作量:

const throttledMethod = (value: number, otherValue: boolean) => {
    throttle(
        () => changeValue(Number(value), otherValue), 
        175, 
        { "trailing": false }
    );
};

但是,调用throttledMethod()只会调用throttle,它会返回changeValue的限制版本。它不会调用生成的限制函数。此外,changeValue只是一个动作创建者 - 它实际上并没有任何事情。

返回(dispatch) => {}的第二个操作创建者正在使用redux-thunk。这很好,因为我们需要它。

您可以通过以下方式获得您正在寻找的功能:

// we only want to set up the throttling once
const throttledChangeValue = throttle(
    (dispatch, value, otherValue) => dispatch(changeValue(Number(value), otherValue)), 
    175, 
    { "trailing": false }
);

// this is using thunk to dispatch the throttled action
const throttledPayOff = (value, otherValue) => dispatch => throttledChangeValue(dispatch, value, otherValue);