오류 경계로 인해 React Router 링크가 작동을 중지함
16140 단어 reactjavascript
아래는 내 앱이 어떻게 생겼는지에 대한 제거된 버전입니다.
/page-with-error
경로로 이동하려고 하면 페이지에 런타임 오류가 있기 때문에 오류 화면이 나타납니다. 그러나 오류 화면에서 집으로 돌아가려고 하면 오류 화면에서 멈춥니다.import React from 'react'
import { BrowserRouter, Link, Routes, Route } from "react-router-dom";
import Homepage from './Homepage';
import PageWithError from './PageWithError';
export default function App() {
return (
<BrowserRouter>
<nav>
<Link to="/">Home</Link>{" "}
<Link to="/page-with-error">Broken Page</Link>
</nav>
<ErrorBoundary>
<Routes>
<Route path="/" element={<Homepage />} />
<Route path="/page-with-error" element={<PageWithError />} />
</Routes>
</ErrorBoundary>
</BrowserRouter>
);
}
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError() {
return { hasError: true };
}
render() {
return this.state.hasError
? <h1>Something went wrong.</h1>
: this.props.children;
}
}
내비게이션이 작동하지 않는 이유
자세히 살펴보면 탐색할 수 없는 이유는 탐색한 후에도
<ErrorBoundary />
구성 요소의 hasError
상태가 여전히 true로 설정되어 있어 어떤 페이지를 탐색하든 오류 경계가 계속해서 오류를 표시하기 때문입니다. 에게.이를 처리하는 가장 쉬운 방법은 URL 위치가 변경될 때마다 false로 전환
hasError
하는 부작용을 트리거하는 것입니다.불행하게도 부작용을 처리하는 React의 기본 방법은 후크입니다:
useEffect
. 후크는 클래스 구성 요소에서 사용할 수 없으며 클래스 구성 요소를 사용하지 않고 오류 경계를 구축할 수 없습니다.해결책
이것이 극복할 수 없는 것처럼 보이더라도 두려워하지 마십시오. 기능 구성 요소와 클래스 기반 오류 경계 구성 요소를 함께 구성하여 경로가 변경될 때 오류를 해제할 수 있습니다.
import React, { useState, useEffect } from 'react'
import { BrowserRouter, Link, useLocation, Routes, Route } from "react-router-dom";
import Homepage from './Homepage';
import PageWithError from './PageWithError';
export default function App() {
return (
<BrowserRouter>
<nav>
<Link to="/">Home</Link>{" "}
<Link to="/page-with-error">Broken Page</Link>
</nav>
<ErrorBoundary>
<Routes>
<Route path="/" element={<Homepage />} />
<Route path="/page-with-error" element={<PageWithError />} />
</Routes>
</ErrorBoundary>
</BrowserRouter>
);
}
/**
* NEW: The error boundary has a function component wrapper.
*/
function ErrorBoundary({children}) {
const [hasError, setHasError] = useState(false);
const location = useLocation();
useEffect(() => {
if (hasError) {
setHasError(false);
}
}, [location.key]);
return (
/**
* NEW: The class component error boundary is now
* a child of the functional component.
*/
<ErrorBoundaryInner
hasError={hasError}
setHasError={setHasError}
>
{children}
</ErrorBoundaryInner>
);
}
/**
* NEW: The class component accepts getters and setters for
* the parent functional component's error state.
*/
class ErrorBoundaryInner extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(_error) {
return { hasError: true };
}
componentDidUpdate(prevProps, _previousState) {
if(!this.props.hasError && prevProps.hasError) {
this.setState({ hasError: false });
}
}
componentDidCatch(_error, _errorInfo) {
this.props.setHasError(true);
}
render() {
return this.state.hasError
? <h1>There was an error</h1>
: this.props.children;
}
}
작동 방식
위의 예에서 기능 구성 요소는 클래스 구성 요소 오류 경계를 래핑합니다. 이전과 마찬가지로 클래스 구성 요소 오류 경계는 모든 하위 오류를 포착합니다. 하위 오류가 포착되면
componentDidCatch()
수명 주기 방법을 사용하여 상위 기능 구성요소의 오류 상태를 설정합니다.React Router의 위치가 변경되면 상위 기능 구성 요소는
useEffect
후크 내에서 오류 상태를 해제하고 새 소품을 하위 구성 요소로 전달합니다. 이렇게 하면 componentDidUpdate()
수명 주기 메서드가 트리거되고 클래스 구성 요소 오류 경계 오류 상태가 해제되어 경로가 변경될 때 새 화면이 렌더링될 수 있습니다.이별 생각
이 구현은 복잡하고 약간 혼란스럽지만 작동합니다. 응용 프로그램 상단 근처가 아니라 경로당 오류 경계를 설정하여 이러한 복잡성을 피할 수 있습니다. 그러나 응용 프로그램의 링크를 끊지 않는 catch all 핸들러를 찾고 있다면 이것이 트릭을 수행해야 합니다.
Reference
이 문제에 관하여(오류 경계로 인해 React Router 링크가 작동을 중지함), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/tylerlwsmith/error-boundary-causes-react-router-links-to-stop-working-50gb텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)