2016-08-15 53 views
0

新的特性「updateNumber」到js和反應,試圖讓一個基本的數獨程序ReactJS - 無法讀取未定義」

當我添加UpdateNumberInCell = {} this.updateNumber作爲在電池組件的屬性。我得到的錯誤:「遺漏的類型錯誤:無法讀取屬性未定義‘updateNumber’。」我在這盯着一個小時,不明白什麼是錯的可能是一些非常基本的

完整代碼:

class Cell extends React.Component { 

    constructor(props) { 
     super(props); 

     this.state = {editing: false}; 
    } 

    editCell() { 
     this.setState({editing: true}); 
    } 

    editingDone() { 
     let number = this.refs.newNumber.value; 
     this.props.updateNumberInCell(number, this.props.index); 
     this.setState({editing: false}); 
    } 

    renderEditing() { 
     return <td><textarea ref="newNumber" onBlur={this.editingDone.bind(this)} onKeyPress={this.editingDone.bind(this)} defaultValue={this.props.children} 
          maxLength="1" cols="1" rows="1" autoFocus /></td>; 
    } 

    renderNormal() { 
     if (this.props.editable) { 
      return <td onClick={this.editCell.bind(this)}>{this.props.children}</td>; 
     } else { 
      return <td>{this.props.children}</td>; 
     } 
    } 

    render() { 
     if (this.state.editing) { 
      return this.renderEditing(); 
     } else { 
      return this.renderNormal(); 
     } 
    } 

} 


class Board extends React.Component { 

    constructor(props) { 
     super(props); 

     let boardList = []; 
     let i = 0; 
     for (let r = 0; r < 3; r++) { 
      boardList.push([]); 
      for (let c = 0; c < 3; c++) { 
       let number = this.props.boardString[i]; 
       if (number !== "0") { 
        boardList[r].push(
          { 
           "index": i, 
           "number": number, 
           "editable": false, 
           "inConflict": false 
          }); 
       } else { 
        boardList[r].push({ 
         "index": i, 
         "number": number, 
         "editable": true, 
         "inConflict": false 
        }); 
       } 
       i++; 
      } 
     } 
     console.log(JSON.stringify(boardList)); 

     this.state = {boardList}; 
    } 

    updateNumber(number, index) { 
     let newBoardList = this.state.boardList; 
     for (let row = 0; row < 3; row++) { 
      for (let col = 0; col < 3; col++) { 
       if (newBoardList[row][col].index === index) { 
        newBoardList[row][col].number = number; 
        this.setState({boardList: newBoardList}); 
       } 
      } 
     } 
    } 

    renderCell(cell, i) { 
     return (
       <Cell key={i} index={cell.index} editable={cell.editable} updateNumberInCell={this.updateNumber}>{cell.number}</Cell>); 
    } 

    render() { 
     return (<div>              {/*map means return a new array and do this function for each element in the list*/} 
        <table> 
         <tbody> 
         <tr> 
          {this.state.boardList[0].map(this.renderCell)} 
         </tr> 
         <tr> 
          {this.state.boardList[1].map(this.renderCell)} 
         </tr> 
         <tr> 
          {this.state.boardList[2].map(this.renderCell)} 
         </tr> 
         </tbody> 
        </table> 
       </div> 
     ); 
    } 

} 


ReactDOM.render(<Board boardString="102840503" />, document.getElementById("sudoku")); 
+0

必須綁定'renderCell'否則,'this'將是不確定的。 –

回答

1

你會得到這個錯誤,因爲你的功能未定義,請參考renderCell。要在回調中獲得正確的this參考,您應該使用bind方法。

工作代碼:

renderCell(cell, i) { 
    return (
      <Cell key={i} index={cell.index} editable={cell.editable} updateNumberInCell={this.updateNumber.bind(this)}>{cell.number}</Cell>); 
} 

render() { 
    return (<div>              {/*map means return a new array and do this function for each element in the list*/} 
       <table> 
        <tbody> 
        <tr> 
         {this.state.boardList[0].map(this.renderCell.bind(this))} 
        </tr> 
        <tr> 
         {this.state.boardList[1].map(this.renderCell.bind(this))} 
        </tr> 
        <tr> 
         {this.state.boardList[2].map(this.renderCell.bind(this))} 
        </tr> 
        </tbody> 
       </table> 
      </div> 
    ); 
} 

或者你可以在構造函數中改用bind

constructor(props) { 
    super(props); 

    this.state = {editing: false}; 

    this.renderCell = this.renderCell.bind(this); 
    this.updateNumber = this.updateNumber.bind(this); 
} 
+0

或者你可以綁定一次在構造函數 – aw04

+0

@ aw04,感謝您的糾正,我會更新答案。 – 1ven