我正在使用一个代表组件(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);
所以...如果我无法设置状态,我就无法以控制的方式设置表单的值。有什么建议吗?
答案 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,
};