Estoy tratando de escribir un cargador ajax simple y me pregunto si puedo evitar que props.children se rendericen en el contenedor principal. El problema es que los niños quieren renderizar, sin importar si Loader quiere mostrarlo o no, y si el renderizado se basa en datos ajax, hay errores.
Ejemplo: https://jsfiddle.net/j8dvsq39/
Ejemplo 2: este ejemplo producirá un error porque this.state.data.user no está definido antes de la solicitud ajax.
Cargador:
import React from 'react' export default React.createClass({ getDefaultProps() { return { text: "Loading", loaded: false }; }, render() { if(this.props.loaded == false) return <div>{this.props.text}</div>; else return <div>{this.props.children}</div>; } })Clase usando Loader
import React from 'react' import Loader from '../helpers/Loader'; import {comm} from '../Comm'; export default React.createClass({ getInitialState() { return {loaded: false, data: null}; }, componentWillMount(){ comm.get("/xxx/xxx", {json: 1}, (back) => { console.log(back); this.setState({loaded: true, data: back}); }); }, render(){ return <Loader loaded={this.state.loaded}>{this.state.data.user.name}</Loader> });La razón es que inicialmente definió data=null y antes de la llamada ajax está usando this.state.data.user.name , arrojará el error:
No se puede leer la propiedad 'nombre' de indefinido
La solución simple es que necesita verificar los datos hasta que no obtenga la respuesta de ajax. Verifique esto:
var Loader = React.createClass({ getDefaultProps() { return { text: "Loading", loaded: false }; }, render() { if(this.props.loaded == false) return <div>{this.props.text}</div>; else return <div>{this.props.children}</div>; } }); var Hello = React.createClass({ getInitialState() { return {loaded: false, data: null}; }, componentWillMount(){ setTimeout(()=>{ this.setState({loaded: true, data: {user:{name: "login"}}}); }, 1000); }, render: function() { var user = null; return <Loader loaded={this.state.loaded}> <div> Hello {this.state.data ? this.state.data.user.name : null} </div> </Loader>; } }); ReactDOM.render( <Hello name="World" />, document.getElementById('container') ); <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> <div id='container'/>