简体   繁体   English

重新提交前最初显示的登录页面-Reactjs

[英]Login page showing initiially before rerender - Reactjs

What's happening is when my user is logged in and refreshes the page, my login page shows up briefly before showing them the actual page. 发生了什么事,当用户登录并刷新页面时,我的登录页面会短暂显示,然后再向他们显示实际页面。 I'd like either a blank page to show up or a loading page to show up instead in the mean time. 同时,我希望显示一个空白页面或一个加载页面。 I'm actually not quite sure why it's even showing up first because I have some data processing happening in componentWillMount() first. 我实际上不太确定为什么它首先出现,因为我首先在componentWillMount()进行了一些数据处理。

Here's the relevant code: 以下是相关代码:

componentWillMount()
{
    let url = "src/php/login.php";

    axios.get(url, {
        params: {
            get_userid : ""
        }
    })
    .then( r => 
    {
        if (r.data)
        {
            console.log(r.data);
            this.props.dispatch({ type: "new_user_id", payload: { id: r.data } });
        }
    })
    .catch( error => console.log(error));       
}



render() {
    var { user_id } = this.props;
    if (!user_id)
    {
        return (
            <div>
                some login logic
                <button onClick={this.new_user_id}>New user</button>

                <div style={{color : "red"}}>
                    { this.state.error && "Could not validate username/password. Please check." }
                </div>

                <form onSubmit={this.handle_submit}>
                    <div>
                        Username: <input id="username" name="username" type="text" />
                    </div>
                    <div>
                        Password: <input id="password" name="password" type="password" />
                    </div>
                    <input type="submit" value="submit" />
                </form>
            </div>
        );
    }

    else
    {
        return (
            <div style={{padding: "0 5px"}}>
                User ID: {user_id}
                <div style={{padding: "5px 0"}}>
                    <Link activeClassName="active" className="default bottom-radius" to='main'>Main Menu</Link>
                    <Link activeClassName="active" className="default bottom-radius" to='search'>Search</Link>
                    <Link activeClassName="active" className="default bottom-radius" to="form">Form</Link>
                    <a className="bottom-radius" style={{ float: "right", color : "blue", backgroundColor: "red", padding: "5px", cursor : "pointer" }} onClick={this.logout}>Logout</a>
                </div>
                <div style={{paddingTop: "10px"}}>
                    {this.props.children}
                </div>

            </div>
        );
    }
  }

user_id is intially "" user_id""

In your componentWillMount() function you have data processing in Promise so React continues to render w/o waiting for promise to resolve/reject. 在您的componentWillMount()函数中,您可以在Promise中进行数据处理,因此React继续呈现w / o,等待承诺解决/拒绝。

To show blank page or any loading state you have to have some flag defined, eg: 要显示空白页或任何加载状态,您必须定义一些标志,例如:

state: {loading: true}

You can add loading state flag in constructor of your component like this: 您可以像这样在组件的构造函数中添加加载状态标志:

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {loading: true};
  }
}

then in your render method have checking of state: 然后在您的render方法中检查状态:

render(){
   ...
   if(this.state.loading){
       return <div>Loading</div>;
   }
   ...
   // all your normal render stuff.
}

and in componentWillMount() after promise resolves set loading to false, if rejects also to false + some error message in same way. 并在promise解析后将componentWillMount()加载设置为false,如果组件也拒绝为false +一些错误消息,则在componentWillMount()

The simple reason is, that the component is mounted and rendered before your ajax request is completed. 简单的原因是,在您的ajax请求完成之前已安装并呈现了该组件。 A typical solution is to show some sort of a loading indicator while component data is being fetched. 一种典型的解决方案是在获取组件数据时显示某种加载指示器。

Basically you need to implement a isLoading flag either in component state or in the reducer. 基本上,您需要在组件状态或reducer中实现isLoading标志。

For example like this 像这样

const ExampleComponent extends Component() {
  constructor() {
    super(props)
    this.state = { isLoading: true }
  }
  componentWillMount() {
    // does and ajax operation, returns a promise
    fetchComponentData()
      .then(() => this.setState({ isLoading: false }))
  }
  render() {
    return (
      {
        this.props.user_id ? (
          <RegularContent />
        ) : (
          this.state.isLoading ? (
            <LoadingIndicator />
          ) : (
            <LoginForm />
          )
        )
      }
    )
  }
}

I also recommend reading about the React Component lifecycle , this gives you a good overview on some dos and don'ts for the lifecycle hooks like componentWillMount , componentDidMount , etc. For example it is recommended that componentDidMount be used for launching any ajax requests for component data instead of componentWillMount . 我还建议阅读有关React Component生命周期的文章 ,这为您提供了一些关于生命周期挂钩的重要事项的概述,例如componentWillMountcomponentDidMount等。例如,建议将componentDidMount用于启动针对组件的任何Ajax请求数据,而不是componentWillMount

Hope this helps! 希望这可以帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM