react-rails:组件在创建记录后不重新呈现
react-rails : component does not re-render after record created
在学习教程时,我试图在通过 AJAX 调用创建新记录(游戏)后重新渲染我的 GamesBox。
记录已保存,我可以通过刷新看到它,但这似乎不是 React 方式...
容器:
var GamesBox = React.createClass ({
getInitialState: function(){
return {
game: this.props.games
}
},
parentGameSubmit (formData){
$.ajax({
url: "/games",
dataType: 'json',
type: 'POST',
data: formData,
success: function(games) {
this.setState({games: games});
}.bind(this),
error: function(response, status, err) {
console.log(this.props.url, status, err.toString())
}.bind(this)
});
},
render () {
return (
<div>
<h1> Hey everyone </h1>
<Game games={this.state.game} />
<GameForm parentGameSubmit={this.parentGameSubmit}/>
</div>
);
}
});
呈现的游戏列表:
var Game = React.createClass({
renderProjectRows: function(){
return(
this.props.games.map(function(game){
return(
<div className="row" style={{marginTop: "20px"}} key={game.id}>
<div className="col-sm-2">
<h2 className="text-center" key={game.id}><a href={"/games/" + game.id}> {game.name} </a></h2>
</div>
</div>
)
})
);
},
render: function() {
return(
<div>
<div className="row" style={{marginTop: "50px"}}>
<div className="col-sm-2">
</div>
<div className="col-sm-2" style={{fontWeight: "bold"}}>
Name
</div>
</div>
{this.renderProjectRows()}
</div>
);
}
});
表格:
var GameForm = React.createClass({
getInitialState: function(){
return {name: ""};
},
resetState: function(){
this.setState({name: ""});
},
newGameSubmit: function(e){
e.preventDefault();
this.props.parentGameSubmit({game: {name: this.state.name, white_castling: this.state.white_castling, black_castling: this.state.black_castling}},
this.resetState);
this.setState({name: ''});
},
handleNameChange: function(e){
this.setState({name: e.target.value});
},
renderGameNameField: function(){
return(
<div className='row'>
<div className='col-sm-4'>
<div className= 'form-group'>
<input
name="game[name]"
type="string"
placeholder="Game name"
value={this.state.name}
onChange={this.handleNameChange}
className="string form-control"
/>
</div>
</div>
</div>
);
},
render: function() {
return(
<div>
<h4 style={{marginTop: "50px"}}> Create New Game </h4>
<form style={{marginTop: "30px"}} onSubmit={this.newGameSubmit}>
<div className='form-inputs'/>
{this.renderGameNameField()}
<div className='row'>
<div className='col-sm-4'>
<input type="submit" value="Save" className='btn btn-primary' />
</div>
</div>
</form>
</div>
);
}
});
游戏控制器:
class GamesController < ApplicationController
before_action :authenticate_user!
def index
@game = Game.all
end
def new
@game = Game.new
end
def create
@game = Game.new(game_params)
respond_to do |format|
if @game.save
@game.update(white_user_id: current_user[:id])
format.html { redirect_to @game, notice: 'Project was successfully created.' }
format.json { render json: Game.all.order(:name)}
else
format.html {render :new}
end
end
end
private
def game_params
params.require(:game).permit(:name, :white_castling, :black_castling)
end
end
请给我一些见解
一切看起来都不错,除了你的表格。当您处于事件处理程序中时范围发生变化,您必须绑定上下文。
onChange={this.handleNameChange.bind(this)}
和
onSubmit={this.newGameSubmit.bind(this)}
试试这个:
var GameForm = React.createClass({
getInitialState: function(){
return {name: ""};
},
resetState: function(){
this.setState({name: ""});
},
newGameSubmit: function(e){
e.preventDefault();
this.props.parentGameSubmit({game: {name: this.state.name, white_castling: this.state.white_castling, black_castling: this.state.black_castling}},
this.resetState);
this.setState({name: ''});
},
handleNameChange: function(e){
this.setState({name: e.target.value});
},
renderGameNameField: function(){
return(
<div className='row'>
<div className='col-sm-4'>
<div className= 'form-group'>
<input
name="game[name]"
type="string"
placeholder="Game name"
value={this.state.name}
onChange={this.handleNameChange.bind(this)}
className="string form-control"
/>
</div>
</div>
</div>
);
},
render: function() {
return(
<div>
<h4 style={{marginTop: "50px"}}> Create New Game </h4>
<form style={{marginTop: "30px"}} onSubmit={this.newGameSubmit.bind(this)}>
<div className='form-inputs'/>
{this.renderGameNameField()}
<div className='row'>
<div className='col-sm-4'>
<input type="submit" value="Save" className='btn btn-primary' />
</div>
</div>
</form>
</div>
);
}
});
- 你不断地在游戏与游戏之间穿梭。即
game: this.props.games
在您的 GameBox
组件中。如果它是在这种情况下的数组,则应该使用游戏。 (我假设这是真的,因为您在 Game
组件中使用了地图函数)。
- 发送成功 ajax 时,您正在更新游戏状态,而不是您实际使用的游戏状态。
如果您想要快速修复,只需在 parentGameSubmit
函数中将 this.setState({games: games});
更改为 this.setState({game: games});
。
在学习教程时,我试图在通过 AJAX 调用创建新记录(游戏)后重新渲染我的 GamesBox。
记录已保存,我可以通过刷新看到它,但这似乎不是 React 方式...
容器:
var GamesBox = React.createClass ({
getInitialState: function(){
return {
game: this.props.games
}
},
parentGameSubmit (formData){
$.ajax({
url: "/games",
dataType: 'json',
type: 'POST',
data: formData,
success: function(games) {
this.setState({games: games});
}.bind(this),
error: function(response, status, err) {
console.log(this.props.url, status, err.toString())
}.bind(this)
});
},
render () {
return (
<div>
<h1> Hey everyone </h1>
<Game games={this.state.game} />
<GameForm parentGameSubmit={this.parentGameSubmit}/>
</div>
);
}
});
呈现的游戏列表:
var Game = React.createClass({
renderProjectRows: function(){
return(
this.props.games.map(function(game){
return(
<div className="row" style={{marginTop: "20px"}} key={game.id}>
<div className="col-sm-2">
<h2 className="text-center" key={game.id}><a href={"/games/" + game.id}> {game.name} </a></h2>
</div>
</div>
)
})
);
},
render: function() {
return(
<div>
<div className="row" style={{marginTop: "50px"}}>
<div className="col-sm-2">
</div>
<div className="col-sm-2" style={{fontWeight: "bold"}}>
Name
</div>
</div>
{this.renderProjectRows()}
</div>
);
}
});
表格:
var GameForm = React.createClass({
getInitialState: function(){
return {name: ""};
},
resetState: function(){
this.setState({name: ""});
},
newGameSubmit: function(e){
e.preventDefault();
this.props.parentGameSubmit({game: {name: this.state.name, white_castling: this.state.white_castling, black_castling: this.state.black_castling}},
this.resetState);
this.setState({name: ''});
},
handleNameChange: function(e){
this.setState({name: e.target.value});
},
renderGameNameField: function(){
return(
<div className='row'>
<div className='col-sm-4'>
<div className= 'form-group'>
<input
name="game[name]"
type="string"
placeholder="Game name"
value={this.state.name}
onChange={this.handleNameChange}
className="string form-control"
/>
</div>
</div>
</div>
);
},
render: function() {
return(
<div>
<h4 style={{marginTop: "50px"}}> Create New Game </h4>
<form style={{marginTop: "30px"}} onSubmit={this.newGameSubmit}>
<div className='form-inputs'/>
{this.renderGameNameField()}
<div className='row'>
<div className='col-sm-4'>
<input type="submit" value="Save" className='btn btn-primary' />
</div>
</div>
</form>
</div>
);
}
});
游戏控制器:
class GamesController < ApplicationController
before_action :authenticate_user!
def index
@game = Game.all
end
def new
@game = Game.new
end
def create
@game = Game.new(game_params)
respond_to do |format|
if @game.save
@game.update(white_user_id: current_user[:id])
format.html { redirect_to @game, notice: 'Project was successfully created.' }
format.json { render json: Game.all.order(:name)}
else
format.html {render :new}
end
end
end
private
def game_params
params.require(:game).permit(:name, :white_castling, :black_castling)
end
end
请给我一些见解
一切看起来都不错,除了你的表格。当您处于事件处理程序中时范围发生变化,您必须绑定上下文。
onChange={this.handleNameChange.bind(this)}
和
onSubmit={this.newGameSubmit.bind(this)}
试试这个:
var GameForm = React.createClass({
getInitialState: function(){
return {name: ""};
},
resetState: function(){
this.setState({name: ""});
},
newGameSubmit: function(e){
e.preventDefault();
this.props.parentGameSubmit({game: {name: this.state.name, white_castling: this.state.white_castling, black_castling: this.state.black_castling}},
this.resetState);
this.setState({name: ''});
},
handleNameChange: function(e){
this.setState({name: e.target.value});
},
renderGameNameField: function(){
return(
<div className='row'>
<div className='col-sm-4'>
<div className= 'form-group'>
<input
name="game[name]"
type="string"
placeholder="Game name"
value={this.state.name}
onChange={this.handleNameChange.bind(this)}
className="string form-control"
/>
</div>
</div>
</div>
);
},
render: function() {
return(
<div>
<h4 style={{marginTop: "50px"}}> Create New Game </h4>
<form style={{marginTop: "30px"}} onSubmit={this.newGameSubmit.bind(this)}>
<div className='form-inputs'/>
{this.renderGameNameField()}
<div className='row'>
<div className='col-sm-4'>
<input type="submit" value="Save" className='btn btn-primary' />
</div>
</div>
</form>
</div>
);
}
});
- 你不断地在游戏与游戏之间穿梭。即
game: this.props.games
在您的GameBox
组件中。如果它是在这种情况下的数组,则应该使用游戏。 (我假设这是真的,因为您在Game
组件中使用了地图函数)。 - 发送成功 ajax 时,您正在更新游戏状态,而不是您实际使用的游戏状态。
如果您想要快速修复,只需在 parentGameSubmit
函数中将 this.setState({games: games});
更改为 this.setState({game: games});
。