提供者内部的useEffect引发警告

时间:2020-02-24 18:40:16

标签: javascript reactjs react-context use-effect react-tsx

为了更好地理解React中的Context API,我创建了以下示例Context:

import * as React from "react";
import {useEffect, useReducer, useState} from "react";

class State {
    private v1: number;
    private v2: number;

    constructor(v1: number, v2: number) {
        this.v1 = v1;
        this.v2 = v2;
    }
    static zero(): State {
        return new State(0, 0);
    }
    bumpV1(): State {
        return new State(this.v1 + 1, this.v2);
    }
    bumpV2(): State {
        return new State(this.v1, this.v2 + 1);
    }
    getV1(): number {
        return this.v1;
    }
    getV2(): number {
        return this.v2;
    }

}
type Action = { type: 'v1' | 'v2' | 'toggle_timer' | 'reset'};
type ContextValueType = {
    state: State,
    dispatch: React.Dispatch<Action>
}

const ContextExample: React.Context<ContextValueType> = React.createContext({} as ContextValueType);
function ContextProvider(props: { children: JSX.Element}): JSX.Element {
    const [interval, updateInterval] = useState(undefined as (NodeJS.Timeout | undefined));
    const reducer: React.Reducer<State, Action> = (prev: State, action: Action) => {
        switch (action.type) {
            case 'v1':
                return prev.bumpV1();
            case 'v2':
                return prev.bumpV2();
            case 'toggle_timer':
                toggleTimer();
                return prev;
            case 'reset':
                clearTimer();
                return State.zero();

        }
    };

    const [state, dispatch] = useReducer(reducer, State.zero());
    function toggleTimer() {
        if (interval) {
            clearInterval(interval);
            updateInterval(undefined);
        } else {
            const ret = setInterval(() => {
                dispatch({ type: 'v1' })
            }, 1000);
            updateInterval(ret);
        }
    }
    function clearTimer() {
        if (interval) {
            toggleTimer();
        }
    }
    useEffect(() => {
        toggleTimer();
        return clearTimer;
    }, []);

    const value = { state, dispatch };

    return <ContextExample.Provider value={value}>{props.children}</ContextExample.Provider>
}

export {ContextExample, ContextProvider};

在这里,我有一个使用toggleTimer()函数启动和停止的计时器,我希望既可以从调度程序中也可以从提供程序本身进行调用(因为我想启动计时器)加载)。

这导致React响应以下警告:

./src/ContextExample.tsx
  Line 74:8:  React Hook useEffect has missing dependencies: 'clearTimer' and 'toggleTimer'. Either include them or remove the dependency array  react-hooks/exhaustive-deps

通读https://github.com/facebook/create-react-app/issues/6880,我不确定最好的方法是添加// eslint-disable-next-line react-hooks/exhaustive-deps还是以其他方式重组我的代码。

0 个答案:

没有答案