2016-09-09 82 views
0

我有困難的時間整理出我的問題在這裏,我有一個反應組件,它調用從它的父項作爲道具傳入的函數。該功能正在按預期執行。但是,在這個函數中,我想每次更新狀態時都要對父項調用第二個函數兩次。出於某種原因,狀態不會在通話之間更新。這是一個非常簡單的井字遊戲應用程序,我試圖吸引用戶移動(如點擊兒童組件),放置玩家移動,然後放置AI的移動。然後讓玩家點擊另一個開放的廣場。更新狀態時React應用程序中的奇怪行爲

下面是相關代碼:

updateBoard(loc) { 
    if(this.state.gameBoard[loc] === 'x' || this.state.gameBoard[loc]=== 'o' || this.state.winner !== null){ 
     //invalid move 
     return; 
    } 
    let currentGameBoard = this.state.gameBoard; 
    currentGameBoard.splice(loc, 1, this.state.turn); 
     //Check if there is a winner or draw 
     if (this.winner(currentGameBoard, this.state.turn)){ 
     this.setState({gameBoard: currentGameBoard, winner: this.state.turn}); 
     return; 
    } else if(this.tie(currentGameBoard)) { 
     //Make game over component visible 
     this.setState({gameBoard: currentGameBoard, winner: 'd'}); 
     return; 
    } 
    this.setState({gameBoard: currentGameBoard, turn: this.state.turn === 'x' ? 'o' : 'x'}); 
    } 

    gameLoop(move){ 
    this.updateBoard(move); 
    this.updateBoard(this.findAiMove(this.state.gameBoard)); 
    } 

出於某種原因,第一個正確的舉動出現。第一個X被放置在玩家點擊的地方,但AI移動根本不會發生。另外點擊棋盤上的棋子將會放置2個點,然後放2個點和2個點,直到遊戲結束。玩家點擊後呼叫gameLoop(),然後通過呼叫updateBoard()與玩家移動和AI移動。此舉是一個簡單的整數,它是要考慮的移動的數組索引。

回答

0

setState是異步的,所以不能保證狀態將在連續調用之間更新。

這意味着如果您撥打updateBoard方法兩次,則狀態可能沒有從第一次調用中更新,以便第二次調用讀取新值。

一個解決您的問題的方法是使用setState回調的說法,一旦國家已經更新了其被激發:

updateBoard(loc, callback) { 
    if(this.state.gameBoard[loc] === 'x' || this.state.gameBoard[loc]=== 'o' || this.state.winner !== null){ 
     //invalid move 
     return; 
    } 
    let currentGameBoard = this.state.gameBoard; 
    currentGameBoard.splice(loc, 1, this.state.turn); 
    let stateUpdate; 
     //Check if there is a winner or draw 
     if (this.winner(currentGameBoard, this.state.turn)){ 
     stateUpdate = { gameBoard: currentGameBoard, winner: this.state.turn }; 
    } else if(this.tie(currentGameBoard)) { 
     //Make game over component visible 
     stateUpdate = { gameBoard: currentGameBoard, winner: 'd'}; 
    } else { 
     stateUpdate = { gameBoard: currentGameBoard, turn: this.state.turn === 'x' ? 'o' : 'x'}; 
    } 

    this.setState(stateUpdate, callback); 
    } 

    gameLoop(move){ 
    this.updateBoard(move,() => this.updateBoard(this.findAiMove(this.state.gameBoard))); 
    } 

現在第二狀態更新後的第一個總是執行。