2016-05-27 60 views
0

我無法在Stack Overflow上找到對此特定情況的答案,我不認爲這是重複的。更改視圖,警告:setState(...):只能更新已安裝或掛載的組件

我有一個表格組件內置的陣營,看起來像這樣:

"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()。這是一個沒有操作。請檢查未定義組件的代碼。

此外,卸載安裝在在適當的時間在控制檯登錄。

我正在使用React路由器,因此可能會將問題考慮在內。

編輯:我還要補充一點,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 
    }); 
    } 
} 

GamesCreatePage

"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 /> 
    ); 
    } 
} 
+0

你能否加上你的反應路由器路由?你的GameActions.create動作是做什麼的?也許它觸發了一個路由改變,所以你的組件被卸載,之後你調用setState? –

+0

@ fabio.sussetto只是添加它們! –

+0

謝謝,你還可以向我們展示GamesCreatePage的內容,我想這個內容反過來呈現你的GamesForm組件(因爲後者不是路由組件)? –

回答

-1

作爲一個建議:嘗試改變componentWillMount()而不是constructor內組件的狀態。 還有一點避免使用this.state = {}使用this.setState({})

也許這不是直接回答你的問題,但改變這個東西,然後再試一次,也許你會得到更多的正確的結果。

請在建議的更改後發表評論,如果還有一些問題,我會盡力提供幫助。

+0

在ES6 +中,您可以使用'this.state = {};',但是當您改變狀態時,您應該使用'this.setState'參見https:// babeljs。IO /博客/ 2015/06/07 /反應-ON-ES6加 –

相關問題