React Router, как вернуть страницу 404 в случае динамических маршрутов, ожидающих параметр? - PullRequest
0 голосов
/ 14 мая 2018

Скажем, у меня есть следующий маршрут, определенный в коммутаторе:

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

В шаблоне я передаю: pageId API, и он возвращает содержимое для этой страницы. Все работает хорошо, однако приложение вылетает, если я передаю значение: pageId, которого не существует (как, например, у меня нет страницы с «контактом»).

Как сделать так, чтобы в этом случае он перенаправлял на страницу 404, чтобы избежать сбоя приложения?

Заранее спасибо.

Ответы [ 2 ]

0 голосов
/ 07 марта 2019

Возможный подход заключается в использовании границ ошибок 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.

0 голосов
/ 14 мая 2018

Поскольку вы просто передаете переменный идентификатор страницы компоненту Route, а не конкретно называете каждый маршрут, вам нужно, чтобы компонент Template возвращал страницу 404 в случае, когда сервер ничего не возвращает.

Коммутатор будет использовать резервный компонент в случае, когда ни один из доступных путей не соответствует данному пути, но это работает только в том случае, если вы используете конкретные именованные пути, т.е. /users, а не с одним маршрутом ссылка на переменные имена страниц.

...