ReactJs 用户登录后显示主页的问题 [英] ReactJs Problem with displaying home page after user logs-in

查看:28
本文介绍了ReactJs 用户登录后显示主页的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 passport.jsjwt 令牌 来处理我的 React 应用程序中的用户身份验证状态.用户登录后,我将令牌存储在 localStorage 中,因此根据 localStorage 中是否有令牌,我将更新 isAuthenticated 状态属性.
现在,当访客用户(未经身份验证的)用户打开该应用程序时,他应该无法访问该应用程序的主页.
所以我划分了访客用户可以访问和经过身份验证的用户可以访问两个不同变量guestLinksauthLinks.
根据 isAuthenticated 属性,我将显示其中之一.

<块引用>

App.js

class App 扩展组件 {使成为() {const authLinks = (<开关><路线精确的路径=/"名称="登录页面"渲染={道具=><登录{...道具}/>}/><路线精确的路径="/404"名称="页面 404"渲染={道具=><Page404 {...道具}/>}/><路线精确的路径="/500"名称="第 500 页"渲染={道具=><Page500 {...道具}/>}/><路线路径=/家"名称=家"渲染={道具=><DefaultLayout {...props}/>}/></开关>);const 访客链接 = (<开关><路线精确的路径=/"名称="登录页面"渲染={道具=><登录{...道具}/>}/><路线精确的路径=/注册"名称="注册页面"渲染={道具=><注册 {...props}/>}/><路线精确的路径="/404"名称="页面 404"渲染={道具=><Page404 {...道具}/>}/><路线精确的路径="/500"名称="第 500 页"渲染={道具=><Page500 {...道具}/>}/></开关>);const currentState = store.getState();控制台.日志("currentState.auth.isAuthenticated:",currentState.auth.isAuthenticated);返回 (<提供者商店={商店}><HashRouter><React.Suspense fallback={loading()}>{console.log(currentState.auth.isAuthenticated)}{/* TODO:不确定这是否总是有效.如果在用户登录后他得到一个空白页面并且他必须重新加载才能被重定向到主页然后这种路由方式可能需要修改*/}{currentState.auth.isAuthenticated ?authLinks : 访客链接}</React.Suspense></HashRouter></提供者>);}}

注意这一行:

{currentState.auth.isAuthenticated ?authLinks : 访客链接}
所以在用户登录后,(所以他通过了身份验证),他被重定向到主页:

class 登录扩展组件 {构造函数(){极好的();this.state = {电子邮件: "",mot_de_passe: "",错误:"};this.onChange = this.onChange.bind(this);this.onSubmit = this.onSubmit.bind(this);}componentDidMount() {//如果用户已经登录并且他尝试访问登录页面,这会将他重定向到主页如果(this.props.auth.isAuthenticated){this.props.history.push("/home");}}//当组件接收到新属性时运行componentWillReceiveProps(nextProps) {//用户登录后,这会将他重定向到主页如果(nextProps.auth.isAuthenticated){this.props.history.push("/home");}如果(nextProps.errors){this.setState({ 错误: nextProps });}}onChange(e) {this.setState({[e.target.name]: e.target.value});}onSubmit(e) {控制台日志(e);//因为它是一个表单,我们不希望它有它的默认行为e.preventDefault();常量用户信息 = {电子邮件:this.state.email,密码:this.state.mot_de_passe};//我们引入的任何动作都将存储在 props 中//this.props.loginUser(userInfo, this.props.history);this.props.loginUser(userInfo);}使成为() {返回 (<div className="app flex-row align-items-center"><容器><Row className="justify-content-center"><Col md="8"><卡组><卡片类名称="p-4"><卡片体><Form noValidate onSubmit={this.onSubmit}><h1>Se 连接器</h1><p className="text-muted">相互联系</p><InputGroup className="mb-3"><InputGroupAddon addonType="prepend"><InputGroupText><i className="icon-user"></i></InputGroupText></InputGroupAddon>{/* WORK_HERE */}<输入名称=电子邮件"类型=文本"占位符=电子邮件"值={this.state.email}onChange={this.onChange}/></输入组><InputGroup className="mb-4"><InputGroupAddon addonType="prepend"><InputGroupText><i className="icon-lock"></i></InputGroupText></InputGroupAddon><输入名称=mot_de_passe"类型=密码"placeholder="Mot de passe"自动完成=当前密码"值={this.state.mot_de_passe}onChange={this.onChange}/></输入组><行><Col xs="6"><按钮颜色="primary" className="px-4">硒连接器</按钮></Col><Col xs="6" className="text-right"><按钮颜色="link" className="px-0">Mot de passe oubliée?</按钮></Col></行></表格></CardBody></卡片><卡片className="text-white bg-primary py-5 d-md-down-none"样式={{ 宽度:44%"}}><CardBody className="text-center"><div><h2>Bienvenue au Viwone SAV</h2><p>Suivez en temps réel l'évolution des opérations du服务 après-vente.</p>

</CardBody></卡片></卡组></Col></行></容器>

);}}

问题是他登录后,得到一个空白屏幕,他必须重新加载页面才能成功显示主页.
似乎 authLinks 的加载速度不够快,以至于应用无法检测到主屏幕的链接.

解决方案

在你的 App.js 中,使用 connect() 获取 isAuthenticated 值> 因此它会在登录后使用 isAuthencticated 的最新值重新呈现,您将看到更新后的网址

I am using passport.js and jwt token to handle the user authentication state in my react app. After the user logs-in, I store the token in localStorage and so depending on whether there's a token or not in the localStorage, I will updated the isAuthenticated state property.
Now, when a guest user (non-authenticated) user, opens the app, he should not be able to access the home-page of the app.
So I devided the routes that the guest user can access and the authenticated user can access to two different variable guestLinks and authLinks.
And depending on the isAuthenticated property, I will display one of those.

App.js

class App extends Component {
  render() {
    const authLinks = (
      <Switch>
        <Route
          exact
          path="/"
          name="Login Page"
          render={props => <Login {...props} />}
        />
        <Route
          exact
          path="/404"
          name="Page 404"
          render={props => <Page404 {...props} />}
        />
        <Route
          exact
          path="/500"
          name="Page 500"
          render={props => <Page500 {...props} />}
        />
        <Route
          path="/home"
          name="Home"
          render={props => <DefaultLayout {...props} />}
        />
      </Switch>
    );

    const guestLinks = (
      <Switch>
        <Route
          exact
          path="/"
          name="Login Page"
          render={props => <Login {...props} />}
        />
        <Route
          exact 
          path="/register"
          name="Register Page"
          render={props => <Register {...props} />}
        />
        <Route
          exact
          path="/404"
          name="Page 404"
          render={props => <Page404 {...props} />}
        />
        <Route
          exact
          path="/500"
          name="Page 500"
          render={props => <Page500 {...props} />}
        />
      </Switch>
    );

    const currentState = store.getState();
    console.log(
      "currentState.auth.isAuthenticated: ",
      currentState.auth.isAuthenticated
    );
    return (
      <Provider store={store}>
        <HashRouter>
          <React.Suspense fallback={loading()}>
            {console.log(currentState.auth.isAuthenticated)}
            {/* TODO: Not sure if this always works. If after the user logsin he gets a blank page and he has to reload to be redirected to home then
            this way of routing may need to modified */}
            {currentState.auth.isAuthenticated ? authLinks : guestLinks}
          </React.Suspense>
        </HashRouter>
      </Provider>
    );
  }
}  

Notice this line:

{currentState.auth.isAuthenticated ? authLinks : guestLinks}
So after the user logs in, (so he is authenticated), he is redirected to the home-page:

class Login extends Component {
  constructor() {
    super();
    this.state = {
      email: "",
      mot_de_passe: "", 
      errors: ""
    };
    this.onChange = this.onChange.bind(this);
    this.onSubmit = this.onSubmit.bind(this);
  }
  componentDidMount() {
    // If the user has already logged-in and he attempts to access the login page this will redirect him to home
    if (this.props.auth.isAuthenticated) {
      this.props.history.push("/home");
    }
  }
  //This runs when the component receives new properties
  componentWillReceiveProps(nextProps) {
    // After the user has logged-in this will redirect him to home
    if (nextProps.auth.isAuthenticated) {
      this.props.history.push("/home");
    }
    if (nextProps.errors) {
      this.setState({ errors: nextProps });
    }
  }

  onChange(e) {
    this.setState({
      [e.target.name]: e.target.value
    });
  }

  onSubmit(e) {
    console.log(e);
    // Since it's a form, we don't want it to have its default behavior
    e.preventDefault();
    const userInfo = {
      email: this.state.email,
      password: this.state.mot_de_passe
    };
    // Any action that we bring-in is going to be stored inside props
    //this.props.loginUser(userInfo, this.props.history);
     this.props.loginUser(userInfo);
  }
  render() {
    return (
      <div className="app flex-row align-items-center">
        <Container>
          <Row className="justify-content-center">
            <Col md="8">
              <CardGroup>
                <Card className="p-4">
                  <CardBody>
                    <Form noValidate onSubmit={this.onSubmit}>
                      <h1>Se connecter</h1>
                      <p className="text-muted">
                        Connectez-vous à votre compte
                      </p>
                      <InputGroup className="mb-3">
                        <InputGroupAddon addonType="prepend">
                          <InputGroupText>
                            <i className="icon-user"></i>
                          </InputGroupText>
                        </InputGroupAddon>
                        {/* WORK_HERE */}
                        <Input
                          name="email"
                          type="text"
                          placeholder="Email"
                          value={this.state.email}
                          onChange={this.onChange}
                        />
                      </InputGroup>
                      <InputGroup className="mb-4">
                        <InputGroupAddon addonType="prepend">
                          <InputGroupText>
                            <i className="icon-lock"></i>
                          </InputGroupText>
                        </InputGroupAddon>
                        <Input
                          name="mot_de_passe"
                          type="password"
                          placeholder="Mot de passe"
                          autoComplete="current-password"
                          value={this.state.mot_de_passe}
                          onChange={this.onChange}
                        />
                      </InputGroup>
                      <Row>
                        <Col xs="6">
                          <Button color="primary" className="px-4">
                            Se connecter
                          </Button>
                        </Col>
                        <Col xs="6" className="text-right">
                          <Button color="link" className="px-0">
                            Mot de passe oubliée?
                          </Button>
                        </Col>
                      </Row>
                    </Form>
                  </CardBody>
                </Card>
                <Card
                  className="text-white bg-primary py-5 d-md-down-none"
                  style={{ width: "44%" }}
                >
                  <CardBody className="text-center">
                    <div>
                      <h2>Bienvenue au Viwone SAV</h2>
                      <p>
                        Suivez en temps réel l'évolution des opérations du
                        service après-vente.
                      </p>
                    </div>
                  </CardBody>
                </Card>
              </CardGroup>
            </Col>
          </Row>
        </Container>
      </div>
    );
  }
}

The problem is that after he logs-in, he get a blank screen and he has to reload the page in order for the home-page to be successfully displayed.
It seems that the authLinks don't get loaded fast enough for the app to be able to detect the link to the home screen.

解决方案

In your App.js, get isAuthenticated value using connect() so it will re-render with latest value of isAuthencticated after login and your will see the updated urls

这篇关于ReactJs 用户登录后显示主页的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆