简体   繁体   中英

My isLoading flag never set true in the constructor()

I'm working whith one representational component (ProjectFormUpdate) and his container (ProjectFormUpdateContainer). From the container, i send an document object Project and a flag isLoading. But in a Constructor() of ProjectFormUpdate, the flag is false... the state is never seted.

The representational componente

    import React, { Component} from 'react';
import ReactDOM from 'react-dom';
import { Projects } from '/imports/api/projects.js';
import PropTypes from 'prop-types'; // ES6
import { withTracker } from 'meteor/react-meteor-data';


export default class ProjectFormUpdate extends Component {
  handleUpdate(event) {
     event.preventDefault();  
     console.log("se modificó el estadoooo") 
     this.setState({
      codigo: ReactDOM.findDOMNode(this.refs.codigoInput).value.trim(),
      nombre: ReactDOM.findDOMNode(this.refs.nombreInput).value.trim()
    });

   }

  handleSubmit(event){

     this.setState({
      codigo: ReactDOM.findDOMNode(this.refs.codigoInput).value.trim(),
      nombre: ReactDOM.findDOMNode(this.refs.nombreInput).value.trim()
    });

  }


    constructor(props) {
        super(props);        
        if (!props.isLoading){

        this.state = {      
          codigo: props.oneProject.codigo,
          nombre: props.oneProject.nombre}       
        }
        else{

          this.state = {      
          codigo: 'dd',
          nombre: 'ff'}    
        }  
      }

  render() {

    const { oneProject, isLoading } = this.props;

    if (!isLoading){
      this.setState = {      
          codigo: this.props.oneProject.codigo,
          nombre: this.props.oneProject.nombre}       




    return (
      <div className="col-xs-11">
       <div className="box box-solid">
         <form className="form" onSubmit={this.handleSubmit.bind(this)} >
         <div className="box-body">
                  <div className="row">
                          <div className="col-xs-2">
                              <input
                                className = "form-control input-sm"
                                type="text"
                                ref="codigoInput"
                                placeholder="Código del Proyecto"
                                value = {this.state.codigo}//this.state.codigo}
                                onChange = {this.handleUpdate.bind(this)}
                              />
                          </div>
                          <div className="col-xs-6">
                              <input
                                className = "form-control input-sm"
                                type="text"
                                ref="nombreInput"
                                placeholder="Título"
                                value = {this.state.nombre }
                                onChange = {this.handleUpdate.bind(this)}
                              />
                           </div>
                </div>


        </div>
        <div className="box-footer">
        <button type="submit" className="btn btn-sm btn-primary btn-flat">Guardar</button>
        </div>
        </form>
     </div>
   </div>

    );
  }
  else {return (<div></div>);}
}}

ProjectFormUpdate.propTypes = {
  // This component gets the task to display through a React prop.
  // We can use propTypes to indicate it is required
  oneProject: React.PropTypes.object,   
  isLoading: React.PropTypes.bool, 
};

The Container

import { Meteor } from 'meteor/meteor';
import { withTracker } from 'meteor/react-meteor-data';
import { Projects } from '/imports/api/projects.js';
import ProjectFormUpdate from './ProjectFormUpdate.jsx';

export default ProjectFormUpdateContainer = withTracker(({ key1 }) => {      
    const sub = Meteor.subscribe('projects');        
    var oneProject = Projects.findOne(key1);
    var isLoading = !sub.ready();    
    return {
        oneProject,
        isLoading,
    };      
})(ProjectFormUpdate);

So... if i can't set the state, i can't set the form's values in a controled way. Any suggestion?

In order to set your components state outside of the constructor() function: you must call this.setState() . this.setState() will set it's first argument as the new state and subsequently call your component's render function.

Your if (!isLoading) statement is very dangerous. Assuming !isLoading == true : your render function will infinitely fire this.setState() , thereby locking your browser.

Your constructor function appears correct, as is. I would allow it to set the initial application state and handle the rest from within the render() function. Alternatively, you could set your initial state within the componentWillMount() or componentDidMount() functions found here .

Within your render() function, I would omit the if (!isLoading) part and instead try returning a loading component if (isLoading == true) .

You can also apply the following logic directly to your <input/> elements to set your component's state with finesse:

<input value={this.state.key} onChange={(event) => this.setState({key: event.target.value})}/>

I've revised your ProjectFormUpdate component as follows:

import React, { Component} from 'react';
import ReactDOM from 'react-dom';
import { Projects } from '/imports/api/projects.js';
import PropTypes from 'prop-types'; // ES6
import { withTracker } from 'meteor/react-meteor-data';

export default class ProjectFormUpdate extends Component {

handleSubmit(event){
  event.preventDefault()
  console.log()
}


constructor(props) {
  super(props);
  if (!props.isLoading) {
    this.state = {
      codigo: props.oneProject.codigo,
      nombre: props.oneProject.nombre
    }
  }
  else {
    this.state = {
      codigo: '',
      nombre: ''
    }
  }
}

render() {

  const { oneProject, isLoading } = this.props;

  if (isLoading) {
    return (
      <div>isLoading == true</div>
    )
  }

  return (
    <div className="col-xs-11">
      <div className="box box-solid">
        <form className="form" onSubmit={this.handleSubmit.bind(this)} >
          <div className="box-body">
          <div className="row">
            {/* Codigo. */}
            <div className="col-xs-2">
              <input className = "form-control input-sm" type="text" ref="codigoInput" placeholder="Código del Proyecto" value={this.state.codigo} onChange={(event) => this.setState({codigo: event.target.value})} />
            </div>

            {/* Nombre. */}
            <div className="col-xs-6">
              <input className = "form-control input-sm" type="text" ref="nombreInput" placeholder="Título" value={this.state.nombre} onChange={(event) => this.setState({nombre: event.target.value}))} />
            </div>
            </div>
          </div>
          <div className="box-footer">
            <button type="submit" className="btn btn-sm btn-primary btn-flat">Guardar</button>
          </div>
        </form>
      </div>
    </div>
  )
}

ProjectFormUpdate.propTypes = {
  oneProject: React.PropTypes.object,
  isLoading: React.PropTypes.bool,
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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