2016-10-06 1 views
1

Как я следую учебному пособию, я пытаюсь выполнить повторную визуализацию своих игр после того, как новая запись (игра) была создана с помощью вызова AJAX.реакция-рельсы: компонент не перерисовывается после создания записи

Запись спасутся, и я могу видеть его освежающим, однако это не кажется, 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 
 

Пожалуйста, ударил меня идеи

ответ

1
  1. Вы постоянно переключаетесь между играми и играми. i.e game: this.props.games в вашем компоненте GameBox. Вы должны использовать игры, если это массив, который в этом случае. (Я предполагаю, что это верно, потому что вы используете функцию отображения на нем в своем компоненте Game).
  2. Вы обновляете состояние игры, когда отправляется успешный аякс, а не состояние игры, которое вы фактически используете.

Если вы хотите супер быстро исправить, вы можете просто изменить this.setState({games: games}); к this.setState({game: games}); в вашей parentGameSubmit функции.

0

Все выглядит хорошо, кроме вашей формы. Изменение области, когда вы находитесь в обработчике событий, вы должны привязать свой контекст.

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> 
 

 
    ); 
 
    } 
 
});

+0

'React.createClass' autobinds все функции уже,' onChange = {this.handleNameChange.bind (this)} 'и' onSubmit = {this.newGameSubmit.bind (this)} 'ничего не изменит. –