我的isLoading标志在构造函数中从未设置为true()

时间:2017-10-15 19:30:57

标签: reactjs meteor meteor-react

我正在使用一个代表组件(ProjectFormUpdate)和他的容器(ProjectFormUpdateContainer)。从容器中,我发送一个文档对象Project和一个标志isLoading。但是在ProjectFormUpdate的Constructor()中,标志为false ...状态永远不会被设置。

代表性组件

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

容器

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

所以...如果我无法设置状态,我就无法以控制的方式设置表单的值。有什么建议吗?

1 个答案:

答案 0 :(得分:2)

为了在constructor()函数之外设置组件状态:您必须调用this.setState()this.setState()会将它的第一个参数设置为新状态,然后调用组件的渲染函数。

您的if (!isLoading)声明非常危险。假设!isLoading == true:您的渲染函数将无限触发this.setState(),从而锁定您的浏览器。

您的构造函数看起来是正确的。我会允许它设置初始应用程序状态并从render()函数中处理其余部分。或者,您可以在componentWillMount()componentDidMount()函数found here中设置初始状态。

render()函数中,我会省略if (!isLoading)部分,而是尝试返回加载组件if (isLoading == true)

您还可以将以下逻辑直接应用于<input/>元素,以便用精巧设置组件的状态:

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

我修改了您的ProjectFormUpdate组件,如下所示:

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