Как обработать асинхронный запрос в оболочке React-router - PullRequest
0 голосов
/ 28 декабря 2018

Я хочу проверить, прошел ли пользователь аутентификацию в моем приложении React.Используя это руководство.

Я написал обертку над моим <Route /> классом, который проверяет, аутентифицирован ли пользователь, затем мы визуализируем компонент, если нет, мы просто перенаправляем его на вход.page.

const IsAuthenticatedRoute = function ({ component: Component, ...rest }) {
    return (
        <Route {...rest} render={async (props) => {
            return (
                await store.isAuthenticatedAsync() === true // here is the point of troubles
                    ? <Component {...props} />
                    : <Redirect to={{
                        pathname: '/sign-in',
                        state: { from: props.location }
                    }} />
            )
        }} />)
}

И я использую его в своем маршрутизаторе следующим образом:

ReactDOM.render(
    <Provider store={appStore}>
        <Router>
            <div>
                <Switch>
                    <Route exact path='/' component={App} />
                    <IsAuthenticatedRoute path='/protected-route' component={Profile} />
                </Switch>
            </div>
        </Router>
    </Provider>
    ,
    document.getElementById('root')
)

Я хочу выполнить мой асинхронный запрос к серверу, чтобы проверить, аутентифицирован ли пользователь.Я пытался добавить ключевое слово async к своим функциям через вызов await, но выдает ошибку: Objects are not valid as a React child (found: [object Promise]). If you meant to render a collection of children, use an array instead..Я почти пытался использовать обещания, но это тоже не помогло.Когда я использую Promise внутри своей функции и возвращаю <Route /> в операторе .then(), React говорит мне: IsAuthenticatedRoute(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null.

Так что я ожидаю обработать свою асинхронную функцию, а затем после того, как получу ответ от сервера, дайте доступ моему пользователю, чтобы посетить эту страницу.Это возможно только при отправке синхронного запроса на мой сервер или есть другие способы сохранить мой код асинхронным и передать пользователя на защищенную страницу?

1 Ответ

0 голосов
/ 30 декабря 2018

Функция async не может быть отображена как компонент, потому что вы будете выполнять Обещание, а не чистую функцию.Чистые функции могут быть отображены, если они возвращают экземпляр компонента.Обещания должны быть разрешены до того, как они могут быть отображены.

Решение состоит в том, чтобы запустить асинхронный вызов, когда компонент смонтирован, и сделать компонент состоящим из состояния, чтобы он мог изменяться при разрешении вызова.Вам нужно будет что-то сделать во время ожидания ответа.Вы можете визуализировать null, но загрузочный счетчик будет более подходящим.Таким образом, у нас всегда будет что-то отображать, и мы не будем сталкиваться с ошибками при попытке отобразить компонент, который еще не определен.

Вот мой быстрый взлом на то, как компонент может выглядеть:

class RouteRender extends React.Component {
  constructor(props) {
    super(props)
    this.state = { authorized: null }
  }

  componentDidMount() {
    // setState is called once the asynchronous call is resolved.
    store.isAuthenticatedAsync().then(
      authorized => this.setState({ authorized})
    )
  }

  render() {
    if(this.state.authorized === true) {
      const { component: Component, componentProps } = this.props
      return <Component {...componentProps} />
    } else if(this.state.authorized === false) {
      return (<Redirect to={{
               pathname: '/sign-in',
               state: { from: props.location }
             }} />)
    }
    return <LoadingSpinner />
  }
}

const IsAuthenticatedRoute = function ({ component: Component, ...rest }) {
  return (
    // render is now a function rather than a Promise.
    <Route {...rest} render={props => <RouterRender componentProps={props} component={Component} />} />
  )
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...