即使 Action 不在组件中,它也会被调度

Action is being dispatched even though it is not in the component

我正在玩 React Hooks,遇到了 useReducer 的绊脚石。我创建了一个简单的 pinPad,它存储一个 pin 到状态,然后将它与一个常量进行比较,如果 2 匹配,则路由到登录页面。 (我知道它不是很复杂!)我正在使用 useReducer 传递一个减速器:

function reducer(state, action) {
    switch (action.type) {
        case "addDigit":
            return state + action.payload;
        case "reset":
            return "";
        default:
            throw new Error();
    }
}

。目前我还没有实现 PIN 检查,而是使用一个组件 link 到“/LoggedIn”页面。

const [state, dispatch] = useReducer(reducer, "");

然后:

<KeyDigit
    digit={v}
    key={v}
    className="keyDigit number"
    buttonAction={e =>
        state.length < 4 && dispatch({ type: "addDigit", payload: e })
                        }
/>

然而,当我 link 到“/LoggedIn”时,我收到一条 "TypeError: buttonAction is not a function" 消息,就好像在渲染组件后调度再次触发。

我的路由器:

<Router>
    <div>
        <Route exact path="/" component={App} />
        <Route path="/LoggedIn" component={LoggedIn} />
    </div>
</Router>

我不知道为什么当我不渲染 App 组件时应该调度 App 组件中包含的任何内容,顺便说一句,我可以手动输入 url of "/LoggedIn"并且没有出现错误消息,所以它似乎与路由器有关。

KeyDigit 组件:

const KeyDigit = ({ digit, className, children, buttonAction }) => {
let id = `id-${digit}`;
return (
    <div
        className={className}
        id={id}
        onClick={e => {
            buttonAction(digit);
        }}
    >
        <svg
            width="100%"
            height="100%"
            viewBox="0 0 141 141"
            xmlns="http://www.w3.org/2000/svg"
        >
            <circle cx="70" cy="70" r="67" className="key keyNumber" />
        </svg>
        <span className="keyDigitNumber">{digit}</span>
        <div className="keyDigitNumber">{children}</div>
    </div>
);

};

您需要在加载组件时阻止事件

<KeyDigit
        digit={v}
        key={v}
        className="keyDigit number"
        buttonAction={e => {
            e.preventDefault();
            state.length < 4 && dispatch({ type: "addDigit", payload: e })
                            }}
    />

因为您正在使用 exact / 路径,即使您在 http://localhost:3000 它会加载 App 组件,所以不要使用 /,而是使用 /home 那么您将只能在 http://localhost:3000/home

上加载它