React Router 如何在动态路由需要参数的情况下 return 404 页面?

React Router how to return 404 page in case of dynamic routes expecting a parameter?

假设我在 Switch 中定义了以下路由:

<Switch>
    <Route path='/:pageId' component={Template} />
<Switch>

在模板中,我将 :pageId 传递给 API,它 returns 是该页面的内容。一切正常,但是如果我传递一个不存在的 :pageId 值,应用程序会崩溃(就像我没有带有 slug "contact" 的页面)。

在这种情况下如何让它重定向到 404 页面以避免应用程序崩溃?

提前致谢。

由于您只是将可变页面 ID 传递给路由组件,而不是具体命名每条路由,因此在服务器 return没什么。

在 none 个可用路径与给定路径匹配的情况下,Switch 将采用直通组件,但这仅适用于您使用特定命名路径的情况,即 /users,而不是一个链接到可变页面名称的路由。

一种可能的方法是利用 React 16 错误边界。然后你可以在你知道路由无效的时候简单地抛出(只要它在渲染方法 IIRC 中)。

class RouteNotFoundError extends Error {
    constructor(...args) {
        super(...args)
        // extending Error is fickle in a transpiler world - use name check instead of instanceof/constructor
        this.name = "RouteNotFoundError"
    }
}

const RouteNotFoundBoundary = withRouter(
    class RouteNotFoundBoundary extends React.Component {
        constructor(props) {
            super(props)
            this.state = { routeNotFound: undefined }
        }
        componentWillReceiveProps(nextProps) {
            if (this.props.location !== nextProps.location) {
                this.setState({routeNotFound: false})
            }
        }
        componentDidCatch(e) {
            if (e.name === "RouteNotFoundError") {
                this.setState({routeNotFound: this.props.location.key})
            } else {
                throw e
            }
        }
        render() {
            if (this.state.routeNotFound === this.props.location.key) {
                return this.props.fallback || <div>Not found!</div>
            } else {
                return this.props.children
            }
        }
    }
)

const Template = props => {
    if (!allMyPages[props.match.params.pageId]) {
        throw new RouteNotFoundError()
    }

    return renderMyPage(allMyPages[props.match.params.pageId])
}

const Example = () => (
    <RouteNotFoundBoundary fallback={<div>Oh no!</div>}>
        <Switch>
            <Route path='/:pageId' component={Template}/>
        </Switch>
    </RouteNotFoundBoundary>
)

不确定这是否是个好主意,但当您知道路由是否有效的代码路径不是呈现 404 页面的最佳位置时,它可能会简化某些情况。