useEffect внутри провайдера выдает предупреждение - PullRequest
0 голосов
/ 24 февраля 2020

Работая, чтобы лучше понять API контекста в React, я создал следующий пример контекста:

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 или иначе реструктурировать мой код.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...