在获取所有信息之前,如何阻止要渲染的React组件? [英] How can I block a React component to be rendered until I fetched all informations?

查看:66
本文介绍了在获取所有信息之前,如何阻止要渲染的React组件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在渲染我的组件之前,我需要获取一些信息.该信息将由API提供,并通过ajax调用获取.

I need to fetch some informations before rendering my component. The information will be provided by an API and fetched with an ajax call.

我只是想在渲染组件之前等待10秒钟,但是它说:

I'm just trying to wait 10 seconds before rendering my component but it says:

Uncaught Invariant Violation: Login.render(): A valid ReactComponent must be returned. You may have returned undefined, an array or some other invalid object.

在履行承诺后我可以渲染我的组件吗?

Can i render my component after the fulfilment of a promise?

/** Page Login */
class Login extends React.Component {

  /**
   * @constructor
   * @param {object} props La fonction super() appelle le parent pour y transmettre ses propriétés
   */
  constructor(props) {
    super(props);

    this.handleFormSubmit = this.handleFormSubmit.bind(this);
  }

  /**
   * Reçoit les valeurs des formulaires
   */
  handleFormSubmit(data) {
    const { dispatch } = this.props;

    dispatch(fetchLoginAuth(data));
  }

  normalRender() {
    return (
      <div id="login-page">
        <div className="container-fluid">
          <div className="row">
            <div className="col-md-2">
              <Link to="/" className="home-link"><img src={BASE_URL + '/assets/img/logo.svg'} alt="Logo" /></Link>
            </div>
          </div>
          <div className="row">
            <div className="col-lg-4 col-lg-offset-4">
              <h1><FormattedMessage {...messages.loginPageTitle} /></h1>
            </div>
          </div>
          {React.cloneElement(this.props.children || <div />, { onSubmit: this.handleFormSubmit, login: this.props.login })}
        </div>
      </div>
    );
  }

  /**
   * Render le component - ReactTransitionGroup
   * @return {JSX} Rend la page Registration
   */
  render() {
    setTimeout(this.normalRender, 10000);
  }
}

我将ES6与JSX,redux一起使用,这是带有react-router的通用路由器.

I use ES6 with JSX, redux, an universal router with react-router.

非常感谢您的帮助!

推荐答案

这是我通常做的事情:

class Login extends React.Component {
    constructor(props) {
        //IMPLEMENT OTHER JUNK HERE
        this.state = {
            data: null //This is what our data will eventually be loaded into
        };
    }
    componentDidMount() {
        this.loadData();
    }
    loadData() {
        /*LOAD DATA, INSERT BELOW LINE IN CALLBACK FUNCTION
            this.setState({
                data: //LOADED DATA
            });
        */
    }
    render() {
        if (!this.state.data) {
            return <div />
        }

        //WE HAVE DATA, DO A NORMAL RENDER
        return (
            <div id="login-page">
                <div className="container-fluid">
                    <div className="row">
                        <div className="col-md-2">
                            <Link to="/" className="home-link"><img src={BASE_URL + '/assets/img/logo.svg'} alt="Logo" /></Link>
                        </div>
                    </div>
                    <div className="row">
                        <div className="col-lg-4 col-lg-offset-4">
                            <h1><FormattedMessage {...messages.loginPageTitle} /></h1>
                        </div>
                    </div>
                    {React.cloneElement(this.props.children || <div />, { onSubmit: this.handleFormSubmit, login: this.props.login })}
                </div>
            </div>
        );
    }
}

这是将要发生的事情的细分...

Here's a breakdown of what is going to happen...

  1. 组件即将加载
  2. componentDidMount()触发,运行loadData()
  3. loadData()启动ajax请求,因为我们喜欢异步数据加载,所以在ajax请求返回数据之前先返回
  4. render()运行.由于this.state.datanull,我们进入了if块,并返回了<div />.
  5. Ajax数据加载完成,并进行了this.setState()调用,这将强制重新渲染.
  6. render()再次运行.由于this.state.data现在包含一个值,因此我们跳过if块并呈现常规内容.
  1. Component is going to load
  2. componentDidMount() fires, runs loadData()
  3. loadData() starts ajax request, returns before ajax request returns data because we love asynchronous data loads
  4. render() runs. Since this.state.data is null, we have pass into the if block, and <div /> is returned.
  5. Ajax data load finishes, and a this.setState() call is made, which forces a re-render.
  6. render() runs again. Since this.state.data contains a value now, we skip over the if block and render our normal stuff.

编辑(2019年10月11日):已迁移 componentWillMount()到componentDidMount()

Edit (11 Oct 2019): Migrated componentWillMount() to componentDidMount()

这篇关于在获取所有信息之前,如何阻止要渲染的React组件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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