2017-10-15 44 views
0

我正在工作whith一个表示组件(ProjectFormUpdate)和他的容器(ProjectFormUpdateContainer)。从容器中,我发送一个文档对象Project和一个标志isLoading。但是在ProjectFormUpdate的Constructor()中,该标志为false ...状态永远不会被注册。我isLoading标志从未在构造函数中设置为true

的代表性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, 
}; 

容器

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

所以......如果我不能设置状态,我不能在controled方式设置窗体的值。任何建议?

回答

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

感谢回答阿尔曼。你的代码帮了我很多。但是,不幸的是,我还没有找到解决这个问题的方法。如果我在构造函数中,或者在componentWillMount()或componentDidMount()中执行它...从未设置状态,因此isLoading始终为真。 – Reactib

+0

嗨,队友。很高兴我能帮上忙。这表明你的'const sub = Meteor.subscribe('projects')'方法不会为'.ready()'返回'true'。我会检查你是否已经使用以下文档正确实现了这个论点:[React Meteor Data](https://github.com/meteor/react-packages/tree/devel/packages/react-meteor-data)和[ Meteor.subscribe()](https://docs.meteor.com/api/pubsub.html#Meteor-subscribe)。为''.onReady()'和'.onStop()'回调函数的输出设置控制台日志可能会有帮助。祝一切顺利! –

相关问题