Javascript 等待单击,直到渲染元素为止

Javascript 等待单击,直到渲染元素为止,javascript,reactjs,Javascript,Reactjs,情况如下:我有一个导航,和登录组件Login只是一个导出的函数,用于让用户登录。是这样的: export function login() { var email = document.getElementById('email').value; var password = document.getElementById('password').value; firebase .auth() .signInWithEmailAndPass

情况如下:我有一个
导航
,和
登录
组件
Login
只是一个导出的函数,用于让用户登录。是这样的:

export function login() {
    var email = document.getElementById('email').value;
    var password = document.getElementById('password').value;
    firebase
        .auth()
        .signInWithEmailAndPassword(email, password)
        .then(() => {
                document.getElementById('close').click();
                document.getElementById('questions').click();
            }
        ).catch(e => console.log(e));
}
这几乎是完美的

这是我的
导航
组件

render() {
    return (
        <BrowserRouter>
            <React.Fragment>
                <Navbar>
                    <Navbar.Header>
                        <Navbar.Brand>
                            <Link id='home' to="/">UczIchApp</Link>
                        </Navbar.Brand>
                    </Navbar.Header>
                    <Nav>
                        <LinkContainer id='about' to='/about'>
                            <NavItem>O nas</NavItem>
                        </LinkContainer>
                        {// The issue starts here
                            this.state.user ?
                                <React.Fragment>
                                    <LinkContainer id="questions" to='/questions'>
                                        <NavItem>Zadania</NavItem>
                                    </LinkContainer>
                                    <NavItem onClick={logout.bind(this)}>Wyloguj się</NavItem>
                                </React.Fragment>
                                :
                                <NavItem onClick={this.openLogin}>Zaloguj się</NavItem>
                        }
                    </Nav>
                </Navbar>
                <Switch>
                    <Route exact path="/about" component={AboutComponent}/>
                    <Route exact path="/questions" component={QuestionsComponent}/>
                    <Route exact path="/" component={HomeComponent}/>
                    <Route path='/question/:id' component={QuestionComponent}/>
                </Switch>
                <ModalComponent show={this.state.show} changeShowState={this.changeShowState}/>
            </React.Fragment>
        </BrowserRouter>
    )
}
render(){
返回(
乌奇查普
O nas
{//问题从这里开始
这个.state.user?
扎达尼亚
威洛古吉·西ę
:
扎洛古吉·西ę
}
)
}
因此,当我登录该用户时,我希望他转到
问题路径。我正试着用click做这件事。但问题是,
Questions
链接尚未呈现,因此我得到了:
TypeError:“document.getElementById(…)为null”
错误


如何使其等待组件渲染?

以您的方式访问DOM节点是一个非常糟糕的主意。

您应该遵循的(反应)流程必须是:

  • 用户输入他的凭证(假设您有
    LoginForm
    组件)
  • 提交表格
  • 提交时,您有一个回调函数,它将调用您的
    login
    函数并将凭据作为参数传递(不将login函数与DOM节点耦合)
  • 如果一切正常,使用
    react路由器
    API将用户重定向到所需的路由。类似于
    login(凭证)。然后(()=>history.push('/questions'))
    。在这里,你可以阅读更多关于
  • 伪代码:

    import React from "react";
    import { withRouter } from "react-router-dom"
    
    class LoginForm extends React.Component {
       constructor (super) {
         this.state = {
           email: null,
           password: null
         }
    
         this.login = this.login.bind(this)
       }
    
    
      login() {
        const { email, password } = this.state
    
        firebase
          .auth()
          .signInWithEmailAndPassword(email, password)
          .then(() => this.props.history.push('/questions'))
          .catch(e => console.log(e))
      }
    
       render() {
         <form onSubmit={this.login}>
          // Controlled inputs
          <input name='email' />
          <input name='password' />
    
          <input type='submit' value='Submit' />
         </form>
       }
    }
    
    // Please checkout: https://stackoverflow.com/a/42716055/4312466
    export default withRouter(LoginForm)
    
    从“React”导入React;
    从“react router dom”导入{withRouter}
    类LoginForm扩展了React.Component{
    建造师(超级){
    此.state={
    电子邮件:空,
    密码:null
    }
    this.login=this.login.bind(this)
    }
    登录(){
    const{email,password}=this.state
    火基
    .auth()
    .使用电子邮件和密码登录(电子邮件、密码)
    .然后(()=>this.props.history.push('/questions'))
    .catch(e=>console.log(e))
    }
    render(){
    //受控输入
    }
    }
    //请结帐:https://stackoverflow.com/a/42716055/4312466
    使用路由器导出默认值(LoginForm)
    
    我建议您仔细查看官方文档。

    您在哪里设置状态中的“用户”属性? 如果用户已登录,可以尝试使用react路由器中的“history.push”按钮。

    您可以重定向用户。有几种方法可以做到这一点,例如:

    如果您的
    登录
    组件扩展了
    React.component
    您可以访问
    历史
    对象,如:

    class Login extends React.Component {
       // use `this.props.history.push('/some/path')` here
    };
    
    因此,您可以将
    此.props.history
    传递给您的
    登录
    功能,并在登录时调用
    推送

    export function login(history) {
        var email = document.getElementById('email').value;
        var password = document.getElementById('password').value;
        firebase
            .auth()
            .signInWithEmailAndPassword(email, password)
            .then(() => {
                    history.push('/questions');
                }
            ).catch(e => console.log(e));
    }
    

    Firebase为我处理用户状态。我有点迷路了。如何启动历史对象?如果有
    扩展React.Component
    ,则不必启动。照原样用就行了。这是这样的工作,因为反应路由器v4,确保你有它。请阅读我提供的链接,因为还有其他选项可以从代码重定向,其中一个肯定会对您有效。为什么要访问逻辑函数中的DOM节点?请结帐,如何做它的反应方式。