如何将支柱传递到反应路由器路由?

问题描述 投票:1回答:1

我正在尝试通过使用firebase构建一个简单的应用程序来深入学习反应路由器(v4),我正在做的是当用户使用gobase使用gobase登录时,他们将被重定向到另一个组件,当他们再次转到根路径时'/'他们将不再看到登录(我通过基于状态重定向来做到这一点)

我有两个问题

我的第一个问题是成功验证用户将按预期重定向到/仪表板,但如果我回去或再次输入根路径,登录页面将简要显示然后重定向..我想因为我的方法不够快这是componentWillMount();

我的第二个问题是我想将一些道具传递到仪表板,但我不知道如何,我一直在寻找和搜索互联网,但我不知道如何实现它...

这是我的login.js,我想将currentUser传递给仪表板,当用户返回登录路径时,如果他们已登录,我想快速重定向它们而不显示登录页面...

  state = {
        currentUser: null,
        successLogin: false
    }

    googleAuth = () => {
        auth.signInWithPopup(provider).then(response => {
            const token = response.credential.accessToken;
            const currentUser = response.user;
        }).catch(error => {
            console.log(error.code , 'occured');
        })
    }

    // firebase.auth().signInWithPopup(provider).then(function(result) {
    //   var token = result.credential.accessToken;
    //   var user = result.user;
    // }).catch(function(error) {
    //   var errorCode = error.code;
    //   var errorMessage = error.message;
    //   var email = error.email;
    //   var credential = error.credential;
    // });

    componentDidMount() {
        auth.onAuthStateChanged(user => {
            if(user) {
                console.log('a user was successfuly logged in')
                this.setState({
                    currentUser: user.displayName,
                    successLogin: true
                })
            } else {
                console.log('eerror')
            }
        })
    }

    componentDidUpdate() {
        if(this.state.successLogin){
            this.props.history.replace("/dashboard");
        } else {
            console.log('not a successful login');
        }
    }

    componentWillMount() {
        if(this.state.successLogin){
            <Redirect to="/dashboard"/>
        }
    }

这是我的仪表板即时为用户创建新状态,因为我不知道如何从登录中获取currentUser状态...

 state = {
        user: null
    }

    componentDidMount(){
       auth.onAuthStateChanged(user => {
            this.setState({
                user: user.displayName
            })
       })
    }
    render(){
        const { user } = this.state;
        return (
            <h1> DashBoard {user}</h1>
            )
    }
}

这是我的routes.js

<BrowserRouter>
     <div>
          <Switch>
            <Route path='/' exact component={Login} />
            <Route path='/register' component={Register} /> 
            <Route path='/dashboard' component={MainDashBoard} />
          </Switch>
      </div>
</BrowserRouter>

我知道我可以使用redux但我不想跳进还原......

reactjs firebase react-router firebase-authentication react-router-v4
1个回答
0
投票

.onAuthStateChanged代码放在路径文件中的componentDidMount方法中,而不是仪表板和登录页面。如果您的路由文件是仪表板和登录组件的最低共同祖先,则在那里处理身份验证并将用户作为prop传递给每个路由。处理基于道具的重定向,而不是在两个组件中进行身份验证。您不能将道具直接放入<Route/>组件中,因此您必须编写公共或私有路线更高阶组件并将道具合并为替换路径组件。

我通常只在路径文件的底部弹出这些,或者你可以将它们存储在自己的文件中并导入它们。

const renderMergedProps = (component, ...rest) => {
  const finalProps = Object.assign({}, ...rest)
  return React.createElement(component, finalProps)
}

const PublicRoute = ({ component, ...rest }) => {
  return (
    <Route
      {...rest}
      render={routeProps => {
        return renderMergedProps(component, routeProps, rest)
      }}
    />
  )
}

const PrivateRoute = ({ component, authed, ...rest }) => {
  return (
    <Route
      {...rest}
      render={routeProps =>
        authed === true ? (
          renderMergedProps(component, routeProps, rest)
        ) : (
          <Redirect
            to={{ pathname: '/login', state: { from: routeProps.location } }}
          />
        )}
    />
  )
}

现在你可以使用这些更高阶的组件来代替<Router/>组件但是你的用户prop合并了(或者你可以使用authed布尔道具来显示是否有人登录,而不是必须传递整个用户对象,在状态中设置authed布尔值,并在onAuthStateChanged注册用户时将其设置为true)。

<BrowserRouter>
     <div>
          <Switch>
            <PublicRoute
              exact 
              path='/' 
              component={Login}   
              authed={this.state.authed} />
            <PrivateRoute
              path="/dashboard"
              component={MainDashBoard}
              user={this.state.user}
            />
          </Switch>
      </div>
</BrowserRouter>
© www.soinside.com 2019 - 2024. All rights reserved.