【发布时间】:2016-09-25 20:48:46
【问题描述】:
我在 Stack Overflow 上找不到这个特定情况的答案,我不认为这是重复的。
我有一个内置在 React 中的表单组件,如下所示:
"use strict";
import React from "react";
import GameActions from "./../../actions/games";
import lodash from "lodash";
export default class GamesForm extends React.Component {
constructor(props) {
super(props);
this.state = this._getInitialState();
this._getInitialState = this._getInitialState.bind(this);
this._onChange = this._onChange.bind(this);
this._onSubmit = this._onSubmit.bind(this);
}
componentWillUnmount() {
console.log("unmounted");
}
componentDidMount() {
console.log("mounted");
}
_getInitialState() {
return {
game: {
homeTeam: "",
homeTeamScore: 0,
visitingTeam: "",
visitingTeamScore: 0,
date: new Date(),
parkName: "",
city: "",
state: "",
tournament: "",
sanction: ""
}
};
}
_onChange(e) {
e.preventDefault();
var newState = lodash.cloneDeep(this.state);
newState.game[e.target.name] = e.target.value;
this.setState(newState);
}
_onSubmit(e) {
e.preventDefault();
GameActions.create(this.state);
this.setState(this._getInitialState);
}
render() {
return (
<form onSubmit={this._onSubmit}>
<div className="form-group">
<div className="row">
<div className="col-xs-10">
<label for="homeTeam">Home Team</label>
<input name="homeTeam" className="form-control input-md" value={this.state.game.homeTeam} onChange={this._onChange} autofocus={true} />
</div>
<div className="col-xs-2">
<label for="homeTeamScore">Score</label>
<input name="homeTeamScore" className="form-control input-md" value={this.state.game.homeTeamScore} onChange={this._onChange} />
</div>
</div>
</div>
<div className="form-group">
<div className="row">
<div className="col-xs-10">
<label for="visitingTeam">Visiting Team</label>
<input name="visitingTeam" className="form-control input-md" value={this.state.game.visitingTeam} onChange={this._onChange} />
</div>
<div className="col-xs-2">
<label for="visitingTeamScore">Score</label>
<input name="visitingTeamScore" className="form-control input-md" value={this.state.game.visitingTeamScore} onChange={this._onChange} />
</div>
</div>
</div>
<hr />
<div className="form-group">
<div className="row">
<div className="col-xs-12">
<label for="date">Date</label>
<input name="date" className="form-control input-md" placeholder="03/27/2016" value={this.state.game.date} onChange={this._onChange} />
</div>
</div>
</div>
<hr />
<div className="form-group">
<div className="row">
<div className="col-xs-12">
<label for="parkName">Park Name</label>
<input name="parkName" className="form-control input-md" placeholder="ex. Riverview Park, Patriots Park" value={this.state.game.parkName} onChange={this._onChange} />
</div>
<div className="col-xs-6">
<label for="parkCity">City</label>
<input name="parkCity" className="form-control input-md" value={this.state.game.parkCity} onChange={this._onChange} />
</div>
<div className="col-xs-6">
<label for="parkState">State</label>
<select name="parkState" className="form-control input-md" defaultValue="0" value={this.state.game.parkState} onChange={this._onChange}>
<option value="0" disabled>Select one</option>
<option value="AK">Alaska</option>
</select>
</div>
</div>
</div>
<hr />
<div className="form-group">
<div className="row">
<div className="col-xs-8">
<label for="tournamentName">Tournament Name</label>
<input name="tournamentName" className="form-control input-md" placeholder="ex. Winter Bump" value={this.state.game.tournamentName} onChange={this._onChange} />
</div>
<div className="col-xs-4">
<label for="tournamentSanction">Sanction</label>
<input name="tournamentSanction" className="form-control input-md" placeholder="ex. USSSA" value={this.state.game.tournamentSanction} onChange={this._onChange} />
</div>
</div>
</div>
<hr />
<div className="form-group">
<button type="submit" className="btn btn-lg btn-success btn-block">Submit</button>
</div>
</form>
);
}
}
我有两种不同的视图,一种包含表单,另一种包含列表。在表单页面上启动时,_onSubmit 函数可以正常工作而不会出现警告。之后,我导航到列表页面,然后返回表单页面并尝试再次提交表单。现在它会触发警告:
警告:setState(...):只能更新已安装或正在安装的组件。这通常意味着您在未安装的组件上调用了 setState()。这是一个无操作。请检查未定义组件的代码。
此外,unmounted 和 mounted 在正确的时间记录在控制台中。
我正在使用 React Router,所以这可能是问题的原因。
编辑:我还应该补充一点,setState 两次都有效,只是第二次发出警告。
编辑:如果您取出GameActions.create(this.state) 行,它不会引发警告。
为什么只有当我导航回表单而不是第一次时才收到错误?我该如何解决?
反应路由器路由
<Router history={hashHistory}>
<Route path="/" component={Navbar}>
<IndexRoute component={IndexPage} />
<Route path="games" component={GamesIndexPage} />
<Route path="games/create" component={GamesCreatePage} />
</Route>
</Router>
动作
export default class GameActions {
static create(game) {
Dispatcher.dispatch({
actionType: GameConstants.CREATE,
game: game
});
}
}
游戏创建页面
"use strict";
import React from "react";
import GamesForm from "./../../components/games/form.jsx";
export default class GamesCreatePage extends React.Component {
constructor(props) {
super(props);
this.state = {};
}
render() {
return (
<GamesForm />
);
}
}
【问题讨论】:
-
能否请您也添加您的反应路由器路由?你的 GameActions.create 动作在做什么?也许它触发了路由更改,所以你的组件被卸载,然后你调用 setState ?
-
@fabio.sussetto 刚刚添加了它们!
-
谢谢,你能不能给我们看看 GamesCreatePage 的内容,我想它会依次渲染你的 GamesForm 组件(因为后者不是路由组件)?
-
@fabio.sussetto 完成!
标签: forms reactjs state react-router lifecycle