Necesito para ir a buscar algo de información antes de la representación de mi componente. La información será proporcionada por la API y se recogen con una llamada ajax.

Sólo estoy tratando de esperar 10 segundos antes de pronunciar mi componente, sino que dice:

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

Puedo dar mis componente después de que el cumplimiento de una promesa?

/** 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);
  }
}

Yo uso ES6 con JSX, redux, un universal router con reaccionar-router.

Muchas gracias por tu ayuda!

InformationsquelleAutor Crak_mboutin | 2016-01-26

5 Comentarios

  1. 32

    Aquí es lo que yo hago normalmente:

    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>
            );
        }
    }

    He aquí un desglose de lo que va a suceder…

    1. Componente se va a cargar
    2. componentDidMount() dispara, corre loadData()
    3. loadData() inicia la petición ajax, devuelve antes de la petición ajax devuelve datos porque amamos de datos asincrónica cargas
    4. render() se ejecuta. Desde this.state.data es null, hemos de pasar a la si el bloque, y <div /> se devuelve.
    5. Ajax carga de datos de los acabados, y una this.setState() se realiza la llamada, que obliga a un re-procesamiento.
    6. render() se ejecuta de nuevo. Desde this.state.data contiene un valor ahora, nos saltamos sobre si el bloque y hacer nuestra la materia normal.

    Edición (11 De Octubre De 2019): Migrado componentWillMount() para componentDidMount()

    • Se ve muy bien! Yo voy a probar
    • para mí, esto sólo funcionaba cuando he añadido el .la longitud de la propiedad para la verificación, aun cuando el estado establece con una matriz vacía. Si establece el estado a null primero, entonces, funciona como se indica. Pero supongo que una matriz vacía devuelve true en reaccionar por alguna razón.
  2. 11

    Siempre vamos a Reaccionar de procesamiento.

    Mientras que usted está haciendo algo asincrónica, muestran un círculo de carga o algo.

    render() {
      <div>
        { this.state.isLoading &&
        <div>Loading.. please wait!</div>
        }
        { !this.state.isLoading &&
        <div>My data has arrived!</div>
        }
      </div>
    }
    • No me gusta círculo de carga, quiero un poco de material de diseño de la barra de carga en la parte superior o como youtube. Gracias por tu respuesta! Es una buena manera
    • ¿Qué debo hacer si ya ha sido un DOM prestados lado del servidor ? No quiero reemplazarlo con un cargador. Quiero mantenerlo. Pero cuando la carga de la página, el lado del cliente, es matar a mi lado servidor prestados contenido 🙁
  3. 3

    Usted puede tratar de algo como

    /** Page Login */
    class Login extends React.Component {
        constructor(props) {
        ...
          this.state = {
            ready: false
          };
        }
        componentWillMount() {
           setTimeout(this.handleLoading, 10000);
        }
        handleLoading() {
          this.setState({ ready: true });
        }
        render() {
           if(!this.state.ready)
             return null;
           return normalRender();
        }
    }
    • Nunca evitar el procesamiento. Devolver nulo puede producir un error. Siempre estás mejor representación de un div vacío.
    • Que hay de malo: verificar aquí: también puede devolver null o false para indicar que no desea nada prestados. Detrás de las escenas, Reaccionar representa un <noscript> etiqueta para trabajar con nuestro actual distinción algoritmo. Al regresar nulo o falso, ReactDOM.findDOMNode(este) devolverá null.
    • Franco Risso: tiene sentido. Por lo que he leído, es mejor que volver de un div vacío, pero se me olvido lo que la lógica detrás de eso.
    • el problema con el vacío divs es que no se puede saber si divs tienen algunos de los estilos que muestra algo en la pantalla por defecto, con <noscript> usted puede estar seguro de que no se mostrará nada.
  4. 2

    Suspender el render parece chapucero…

    ¿Por qué no representar una parte de su componente con algunos de marcador de posición-sub-componente..
    y luego, cuando la llamada ajax acabados, el fuego de una acción para cambiar el estado y hacer que su componente original.

    Va a ser mejor, tanto en términos de experiencia de usuario y la elegancia.

    • Quiero tener menos de interfaz de usuario de las transformaciones posibles. No me gusta esto -> imgur.com/p2ZcsbF
  5. 2

    Yo habría hecho de este un comentario en la parte superior de responder, pero no tengo la reputación.

    componentWillMount() ahora es obsoleto. Por lo que es mejor para mover el loadData llamada al constructor

    class Menu extends Component {
    
    state = {}
    
    constructor(props) {
        super(props)
        loadData().then(data =>
            this.setState({data: data})
        )
    }
    
    async loadData() {
      //get your data
    }
    
    render() {
        if (isEmpty(this.state)) {
            return <div>Loading</div>
        }
        return (
            <div id="site">
                {data}
            </div>
        )
     }

Dejar respuesta

Please enter your comment!
Please enter your name here