Обработка реагирующего контекста при возникновении границы ошибки - PullRequest
0 голосов
/ 22 апреля 2020

У меня есть компонент, предоставляющий контекст (= поставщик), и некоторые дочерние компоненты используют этот контекст.

Мой поставщик также переносит компонент ErrorBoundary React в случае дочерних элементов cra sh. Оттуда, если происходит ошибка, компонент ErrorBoundary React обновляет некоторые значения в моем контексте.

Но похоже, что значение не обновляется, и я не знаю почему.

Здесь как выглядит мой код:


const MyContext = React.createContext<{
    state: FsState;
    setState: Dispatch<SetStateAction<FsState>> | null;
}>({ state: { ...initState }, setState: null });

    const [state, setState] = useState({ ...initState });
    const handleError = (error: Error): void => {
        setState({
            ...state,
            status: {
                ...state.status,
                hasError: !!error
            }
        });
    };
    return (
        <MyContext.Provider value={{ state, setState }}>
            <ErrorBoundary
                onError={handleError}
            >
                {children}
            </ErrorBoundary>
        </MyContext.Provider>
    );

Компонент ErrorBoundary:

class ErrorBoundary extends React.Component<Props, State> {
    constructor(props: Props) {
        super(props);
        this.state = { error: null, errorInfo: null };
    }

    componentDidCatch(error: Error, errorInfo: ErrorInfo): void {
        this.props.onError(error);
        this.setState({
            error,
            errorInfo
        });
    }

    render(): React.ReactNode {
        const { error, errorInfo } = this.state;
        const { children } = this.props;
        if (errorInfo) {
            return (
                <>
                    <div
                    >
                        <h1>
                            Something went wrong.
                        </h1>
                    </div>
                    <div>{children}</div>
                </>
            );
        }

        return children;
    }
}

И дочерний компонент (моего провайдера + ErrorBoundary)

export const ChildElement = () => {
  const {
    state: { status },
  } = useContext(MyContext);
  if (status.hasError) {
    return <div>I crashed but I'm in safe mode</div>;
  }
  throw new Error("test test"); // trigger an error
  return <div>I'll never work</div>;
};

Я никогда не захожу внутрь if loop, несмотря на тот факт, что при отладке componentDidCatch корректно срабатывает.

1 Ответ

0 голосов
/ 23 апреля 2020

Благодаря вашей игровой площадке @Shlang я нашел проблему.

Это было действительно что-то более глубокое. У меня есть другой дочерний компонент, имеющий useEffect и использующий также setState для обновления некоторых других значений.

Дело в том, что он переопределял hasError:true обратно на hasError:false, потому что по какой-то асинхронной причине он был выполнен после того, как ошибка была обнаружена ErrorBoundary.

Я сделал обходной путь переместив атрибут hasError в другой хук useState.

Спасибо!

...