【问题标题】:React not rendering component within if block在 if 块中反应不渲染组件
【发布时间】:2018-07-07 10:42:43
【问题描述】:

我正在尝试使用 firebase 创建一个受保护的路由组件,我有以下设置

import React, { Component } from 'react';
import { Route, Redirect } from 'react-router-dom';

import firebase from 'firebase';

firebase.initializeApp({
    apiKey: 'xxxxxx',
    authDomain: 'xxxxxx',
    databaseURL: 'xxxxxx',
    projectId: 'xxxxxx',
    storageBucket: 'xxxxxx',
    messagingSenderId: 'xxxxxx',
});

class ProtectedRoute extends Component {
    componentWillMount() {}

    render() {
        const { component: Component, layout: Layout, redirect, auth: isAuthorized, ...rest } = this.props;

        if (!this.props.hasOwnProperty('auth') && !this.props.hasOwnProperty('layout')) {
            return <Route {...this.props} />;
        }

        const template = Layout ? (
            <Layout>
                <Component />
            </Layout>
        ) : (
            <Component />
        );

        if (!this.props.hasOwnProperty('auth') && this.props.hasOwnProperty('layout')) {
            return <Route {...rest} component={() => template} />;
        }

        if (isAuthorized) {
            firebase.auth().onAuthStateChanged(user => {
                if(!user) {
                    console.log(user)
                    return redirect ? <Redirect to={{ pathname: redirect }} /> : <Route render={() => <div>Unauthorized</div>} />;
                }
            })
        }

        return <Route {...rest} render={() => template} />;
    }
}

export default ProtectedRoute;

我的路由是这样设置的,如果路由应该是私有的,我可以通过它

import Route from './containers/ProtectedRoute';
 <Switch>
    <Route exact path="/" component={LandingPage} />
    <Route path="/private" auth={true} component={PrivatePage} />
    <Redirect to="/" />
  </Switch>

我希望发生的事情是,当访问/private 时,我应该触发firebase.auth().onAuthStateChanged 调用,而在返回null 时,我应该触发重定向逻辑。

相反,我仍在点击return &lt;Route {...rest} render={() =&gt; template} /&gt;;

同时,firebase 调用中的 console.log 正在输出 null

【问题讨论】:

  • 如果我没记错的话,你总是需要先检查if (isAuthorized) {...}
  • firebase.auth().onAuthStateChanged 是异步的,因此您的if (isAuthorized) { ... } 中的return 语句永远不会在渲染中使用,因此return &lt;Route {...rest} render={() =&gt; template} /&gt;; 将始终在这种情况下运行。
  • @Tholle 详细信息电子邮件 e reg e audzieci e
  • 我认为 return 语句在 onAuthStateChanged 的回调中它仍然会运行?
  • 啊,我明白了,谢谢,我愚蠢地认为这是异步的,所以我认为我应该将其移至生命周期挂钩并以不同的方式设置流程?

标签: javascript reactjs firebase-authentication


【解决方案1】:

firebase.auth().onAuthStateChanged 是异步的,所以if (isAuthorized) { ... } 中的 return 语句永远不会运行。

您可以改为将此逻辑放入 componentDidMount 并将最新更改的结果存储在您的组件 state 中并使用它。

示例

class ProtectedRoute extends Component {
  auth = firebase.auth();
  state = { user: this.auth.currentUser };

  componentDidMount() {
    this.unsubscribe = this.auth.onAuthStateChanged(user => {
      this.setState({ user });
    });
  }

  componentWillUnmount() {
    this.unsubscribe();
  }

  render() {
    const {
      component: Component,
      layout: Layout,
      redirect,
      auth: isAuthorized,
      ...rest
    } = this.props;
    const { user } = this.state;

    if (
      !this.props.hasOwnProperty("auth") &&
      !this.props.hasOwnProperty("layout")
    ) {
      return <Route {...this.props} />;
    }

    const template = Layout ? (
      <Layout>
        <Component />
      </Layout>
    ) : (
      <Component />
    );

    if (
      !this.props.hasOwnProperty("auth") &&
      this.props.hasOwnProperty("layout")
    ) {
      return <Route {...rest} component={() => template} />;
    }

    if (isAuthorized && !user) {
      return redirect ? (
        <Redirect to={{ pathname: redirect }} />
      ) : (
        <Route render={() => <div>Unauthorized</div>} />
      );
    }

    return <Route {...rest} render={() => template} />;
  }
}

【讨论】:

    猜你喜欢
    • 2021-06-04
    • 1970-01-01
    • 1970-01-01
    • 2016-11-15
    • 2020-03-08
    • 2020-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多