Я пришел к тому же решению, что у вас есть, какие-нибудь советы о том, как мы можем проверить этот HOC с Jest & Enzyme?

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

У меня есть следующий код:

import React from 'react'
//other imports
import {withRouter} from 'react-router'

class User extends React.Component {
  constructor(props) {
    super(props)
    console.log('props', props)
    let user = JSON.parse(localStorage.getItem('userDetails'))
    if(!user || !user.user || props.match.params.steamId !== user.user.steamId) {
      props.history.push('/')
    } else {
      this.props.updateUserState(user)
      this.props.getUser(user.user.steamId)
    }
  }

  //render function
}

//mapStateToProps and mapDispatchToProps

export default withRouter(connect(mapStateToProps, mapDispatchToProps)(User))

Маршрутизатор:

render() {
    return (
      <Router>
        <div>
          <Route exact path="/" component={Main}/>
          <Route path="/user/:steamId" component={User}/>
          <Route path="/completelogin" component={CompleteLogin}/>
        </div>
      </Router>
    )
  }

Я попытался войти, чтобы проверить, введено ли условие, но я получаю сообщение об ошибке, в котором говорится, что он не может прочитать свойства null.

Есть ли способ исправить мою проблему, а также лучший подход для удовлетворения моих требований? где конкретные компоненты будут строго доступны только авторизованным пользователям

 Andrej Naumovski23 сент. 2017 г., 15:29
@ShubhamKhatri Спасибо, это сработало при добавлении в componentWillMount. Я все еще новичок в React и изучаю жизненный цикл компонента.
 Jaxx23 сент. 2017 г., 15:29
Как сказал @Shubham Khatri, вы не должны помещать какую-либо логику в конструктор, вместо этого используйте методы жизненного цикла. Кроме того, будьте осторожны, вы используете обаprops а такжеthis.props внутри того же метода.
 Andrej Naumovski23 сент. 2017 г., 15:36
@ MatthewBarbara Я добавил код роутера в свой вопрос. Маршрутизатор является BrowserRouter. Кроме того, добавление моей логики в componentWillMount работало, когда я рендерил обычный HTML в моем методе рендеринга, когда я добавлял пользовательский компонент в компонент User, он снова завершался сбоем.
 Matthew Barbara23 сент. 2017 г., 15:30
Можете показать код роутера? Где фактические маршруты настроены. Обычно это в основном / app / index файле. Я подозреваю, что проблема исходит оттуда.
 Shubham Khatri23 сент. 2017 г., 15:24
В идеале переменная аутентификации должна иметь значение false, а затем проверить условие в componentWillMount или componentDidMount, а не в конструкторе, см. Этоstackoverflow.com/questions/44434041/...

Ответы на вопрос(2)

ответ Мэтью Барбары, хотя и абсолютно правильный, излишне сложен. С RR4 вы можете просто использовать компонент Redirect для обработки ваших перенаправлений. Видетьhttps://reacttraining.com/react-router/web/api/Redirect для получения дополнительной информации.

import React, { Component } from "react";
import { connect } from "react-redux";
import { Redirect } from "react-router-dom";

export default function requireAuth (WrappedComponent) {

  class Authentication extends Component {

    render () {

      if (!this.props.authenticated) {
        return <Redirect to="/"/>
      }

      return <WrappedComponent { ...this.props }/>
    }
  }

  function mapStateToProps (state) {
    return { authenticated: state.authenticated }
  }

  return connect(mapStateToProps)(Authentication);
}
 Tinus Wagner04 мая 2018 г., 14:31
Я пришел к тому же решению, что у вас есть, какие-нибудь советы о том, как мы можем проверить этот HOC с Jest & Enzyme?
Решение Вопроса

Предупреждение: в следующем ответе используется старый контекстный API React. Если вы используете V16.3 +, следующий ответ может не относиться к вам

Итак, согласно вашей логике, неавторизованным пользователям запрещен доступ к компоненту User. Просто и честно. С этим проблем нет.

Но меня беспокоит то, что вы проверяете, вошел ли пользователь в компонент, в который не должны входить неаутентифицированные пользователи. Это неверно, на мой взгляд, потому что:

Это дополнительная поездка для нашей программы - добавляет лишнюю ненужную неэффективность. Есть вероятность, что с маршрутизатора мы переходим к компоненту User, а последний отправляет нас обратно к первому. Пинг-понг.

Пользовательский компонент выглядит грязным. Имея неуместную логику. Да не имеет значения. Поскольку проверка подлинности не должна выполняться в пользовательском компоненте. Пользовательский компонент должен содержать пользовательские материалы.

Как вы думаете, если вместо того, чтобы попасть внутрь компонента User для проверки аутентификации пользователей, мы проверим это в маршрутизаторе? Пользовательский компонент, как его называют, предназначен для пользователей, и логика проверки аутентификации должна быть удалена оттуда.

Хорошо, это круто. Но как?

Мы можем создатьКомпонент высшего порядка (HOC) который в качестве аргумента будет принимать любой компонент, переданный ему. Затем мы добавляем логику аутентификации в HOC и, наконец, в зависимости от используемой логики, мы можем либо перенаправить на домашнюю страницу, либо разрешить запрос данному компоненту.

Для того, чтобы HOC смог выполнить вышеописанное, ему необходим доступ к:

Государственный. Нам нужно знать, вошел ли пользователь в систему и в каком состоянии мы храним такие данные.Router. Возможно, нам нужно перенаправить пользователей.

Давайте назовем HOCrequired_auth, Вот код этого:

import React, { Component } from 'react';
import { connect } from 'react-redux';

export default function(ComposedComponent) {
    class Authentication extends Component {
        static contextTypes = {
            router: React.PropTypes.object
        }

        componentWillMount() {
            if (!this.props.authenticated) {
                this.context.router.history.push('/');
            }
        }

        componentWillUpdate(nextProps) {
            if (!nextProps.authenticated) {
                this.context.router.history.push('/');
            }
        }

        render() {
            return <ComposedComponent {...this.props} />
        }
    }

    function mapStateToProps(state) {
        return { authenticated: state.auth.authed };
    }

    return connect(mapStateToProps)(Authentication);
}

Как видите, здесь не происходит никакой черной магии. Что может быть запутанным, так это

static contextTypes = {
    router: React.PropTypes.object
}

context похоже наprops но это позволяет нам пропускать уровни в нашей иерархии компонентов

Потому чтоthis.context очень легко получить доступ и злоупотреблять,реагировать заставляет нас определять контекст таким образом.

Не используйте контекст если вы действительно не знаете, что делаете. Вариант использования для контекста не так распространен. Узнайте больше о том, какие могут быть последствияВот

Чтобы сделать вывод о нашем HOC, он просто принимает компонент в качестве аргумента и либо перенаправляет его на домашнюю страницу, либо возвращает компонент, который мы передадим ему.

Теперь, чтобы использовать его, в файле маршрута мы импортируем HOC

 import RequiredAuth from './components/auth/required_auth';

и любые маршруты, которые мы хотим защитить от неавторизованных пользователей, мы просто маршрутизируем так:

<Route path="/user" component={RequiredAuth(User)}/>

Строка выше будет либо направлена ​​на домашнюю страницу, либо вернет компонент, который мы передаем,User

Рекомендации:https://facebook.github.io/react/docs/higher-order-components.html https://facebook.github.io/react/docs/context.html

 Matthew Barbara06 февр. 2018 г., 12:59
Функция mapStateToProps делает эту часть
 Andrej Naumovski24 сент. 2017 г., 01:30
Вау! Очень красивое и элегантное решение, я новичок в React и еще не осознал всех недостатков, но теперь все это в перспективе. Спасибо!
 Tomas30 янв. 2018 г., 23:14
Я что-то упустил ... как этот HOC должен был получить реквизит, когда ни один не был отправлен? Как это получаетсяthis.props.authenticated?
 Matthew Barbara24 сент. 2017 г., 10:51
Добро пожаловать. Пожалуйста, поделитесь этой информацией. Давайте поможем разработчикам писать умнее.

Ваш ответ на вопрос