使用带有redux的生命周期方法与在render方法中检查prop状态

时间:2018-05-05 07:26:23

标签: javascript reactjs redux

redux中的这个流程有什么问题吗?我在我的reducer中更改了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 :(得分:1)

它们都是有效的方式,除了componentWillReceiveProps在反应v16.3中已弃用,因此最好使用componentDidUpdate。我会简化逻辑如下:

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

但有一个区别是,使用Redirect您不必创建类组件,但您可以在无状态组件中使用它,它甚至不必在{{1}内}或已连接Route

withRouter

答案 1 :(得分:0)

你的两个方法都是等价的,因为Redirect也替换了当前的历史堆栈,this.props.history.replace()也是如此。您可以使用任何方法。

另外考虑到React想要从componentWillReceiveProps开始弃用v17,您最好将componentDidUpdate用于相同的

但是componentDidUpdate这里有一点点缺点,因为只有一小段时间Form可见,然后会发生重定向,这可能是糟糕的用户体验。

因此,考虑React中的未来发展,您可以使用Redirect方法而不是进行道具比较并使用history.replace()

答案 2 :(得分:0)

正如其他人所说,他们都是有效的。

从反应的角度来看,登录组件应该正好处理 - 登录。

我希望有一个比登录页面更高的组件(可能是应用程序),来做是否显示登录表单或重定向的逻辑。例如。像这样的东西:

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}/>);

这里的好处是您可以轻松测试您的登录表单,并且可以非常轻松地在其他组件中进行组合。您的路由问题实际上是全局性的,并且这些问题可以通过您的应用程序排在最前面。