Использование метода жизненного цикла с редуксом по сравнению с проверкой состояния реквизита в методе рендеринга - PullRequest
0 голосов
/ 05 мая 2018

Что-то не так с этим потоком в редуксе? Я изменяю isAuthenticated в моем редукторе, как это

export function userReducer(state=initState, action) {
  switch(action.type){
    case AUTH_SUCCESS:
      return { 
        ...state,
        isAuthenticated: true
      }
      //...
      //...
  }
}

поэтому в моем рендере я проверяю isAuthenticated, если он равен true, я перенаправляю пользователя для входа.

@connect(state => state.user, {loginUser})
class LoginForm extends React.Component {

  constructor() {
    super()
    this.state = {
      email: '',
      password: ''
    }
  }

  handleSubmit() {
    const { email, password } = this.state
    this.props.login(email, password)
  }

  render(){
    const { email, password } = this.state

    return(
      <div>
        {this.props.user.isAuthenticated && <Redirect to={'/dashboard'} />}

        <Form input={{email, password}} handleSubmit={this.handleSubmit}  />
      </div>
    )
  }
}

export default LoginForm

Другой способ - сделать метод рендеринга чище, я использую componentWillRecieiveProps

componentWillReceiveProps(nextProps) {
  if(nextProps.user.isAuthenticated !== this.props.user.isAuthenticated && nextProps.user.isAuthenticated) {
      this.props.history.replace('/dashboard')
  }
}

Какой из них подходит и почему?

Ответы [ 3 ]

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

Оба ваших метода эквивалентны, поскольку Redirect также заменяет текущий стек истории, как и this.props.history.replace(). Вы можете использовать любой из методов.

Также учитывая, что React хочет исключить componentWillReceiveProps с v17 и далее, лучше использовать componentDidUpdate для того же

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

Итак, рассмотрите будущее развитие в React, вы можете использовать подход Redirect вместо того, чтобы сравнивать и использовать history.replace()

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

Как уже говорили другие, они оба действительны.

Просто с реактивной точки зрения компонент входа в систему должен обрабатывать именно это - вход в систему.

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

import {withRouter} from 'react-router-dom';

class App {
  render() {
    if (this.props.user.isAuthenticated && this.props.location === '/login') {
      return <Redirect to={'/dashboard'} />;
    }
    return (<div>
      REST OF APP HERE
    </div>);
  }
}

export default withRouter(props => <App {...props}/>);

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

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

Они оба допустимы, за исключением того, что componentWillReceiveProps устарело в реакции v16.3, поэтому было бы лучше использовать componentDidUpdate. И я бы упростил логику следующим образом:

componentDidUpdate(prevProps) {
  if(prevProps.user.isAuthenticated !== this.props.user.isAuthenticated) {
      this.props.history.replace('/dashboard')
  }
}

Однако есть одно отличие: с Redirect вам не нужно создавать компонент класса, но вы можете использовать его в компоненте без состояния, и он даже не должен быть внутри Route или подключен withRouter.

const SomeComponent = ({ isLogged }) => (
  <div>
    {isLogged <Redirect to="/path" />}
    <div>something</div>
  </div>
)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...