簡體   English   中英

如何從孩子到父母的狀態做出反應

[英]How to get state from child to parent react

我是React的新手

我有兩個組成部分。 父母Square ,孩子Row

我想從Row到父級獲取setValues cellTopcellLeft並使用它。

我該怎么做。

我的代碼在下面

 var Square = React.createClass({ getInitialState: function () { return { countRow: 4, countCol: 4, mouseOnTable: false, onDelRow: false, onDelCol: false } }, appendCol: function() { var countColNew = this.state.countCol + 1; this.setState({countCol: countColNew}); //change initiale state "countCol" (add new column) //console.log(this.state.countCol) }, appendRow: function() { var countRowNew = this.state.countRow + 1; this.setState({countRow: countRowNew}); //change initiale state "countRow" (add new row) //console.log(this.state.countRow) }, deleteCol: function() { var countColNew = this.state.countCol - 1; this.setState({countCol: countColNew}); //change initiale state "countCol" (delete col) //console.log(this.state.countCol) }, deleteRow: function() { var countRowNew = this.state.countRow - 1; this.setState({countRow: countRowNew}); //change initiale state (delete row) //console.log(this.state.countRow) }, hiddenButtons: function(){ var mouseOnTableNew = true; this.setState({mouseOnTable: mouseOnTableNew}) }, showButtons: function(){ var mouseOnTableNew = false; this.setState({mouseOnTable: mouseOnTableNew}) }, render: function() { var timeOut; return ( <div className='square'> <table className='square__table' onMouseOver={this.hiddenButtons} onMouseLeave={() => {timeOut=setTimeout(this.showButtons,200)}}> <Row countRow={this.state.countRow} countCol={this.state.countCol} ref={(ref) => this.state} /> </table> <button className="square__button square__button_append square__button_col-append" onClick={this.appendCol}> </button> <button className="square__button square__button_delete square__button_col-delete" style={this.state.countCol===1 || this.state.mouseOnTable===false || this.state.onDelRow===true ? {visibility: "hidden"} : {visibility: "visible"}} onClick={this.deleteCol} onMouseOver={() => {clearTimeout(timeOut); this.setState({onDelCol:true})}} onMouseLeave={() => {this.setState({onDelCol:false})}}> </button> <button className="square__button square__button_append square__button_row-append" onClick={this.appendRow}> </button> <button className="square__button square__button_delete square__button_row-delete" style={this.state.countRow===1 || this.state.mouseOnTable===false || this.state.onDelCol===true ? {visibility: "hidden"} : {visibility: "visible"}} onClick={this.deleteRow} onMouseOver={() => {clearTimeout(timeOut); this.setState({onDelRow:true})}} onMouseLeave={() => {this.setState({onDelRow:false})}}> </button> </div> ) } }) //================================================== var Row = React.createClass({ getInitialState: function(){ return { cellTop: 0, cellLeft: 0, } }, createCol: function() { var columns = []; for(let i = 0; i < this.props.countCol; i++){ columns.push(this.createCell) } return columns; }, createRow: function (k) { return ( <tr key={k}> {this.createCol().map(function(cell,key){ return ( cell(key) ) })} </tr> ) }, createCell: function(k){ return ( <td key={k}> <div className="square__cell" onMouseOver={this.getMousePosition}></div> </td> ) }, getMousePosition: function(element){ let coordinates = element.target.getBoundingClientRect(); let top = coordinates.top; let left = coordinates.left; this.setState({ cellTop: top, cellLeft: left }) }, render: function(){ var lines = [] for (let i = 0; i < this.props.countRow; i++) { lines.push(this.createRow(i)) } return ( <tbody> {lines} </tbody> ) } }) 

我建議您完全不要在組件中使用狀態。 當您要控制子組件的父組件時,這只會導致問題。

代替,

  • 使所有組件通過道具接收數據
  • 將狀態和所有數據移動到外部對象(存儲)中
  • 當數據更改時,使商店更新您的組件
  • 從組件只是更新存儲

看看https://github.com/reflux/refluxjs

+---------+       +--------+       +-----------------+
¦ Actions ¦------>¦ Stores ¦------>¦ View Components ¦
+---------+       +--------+       +-----------------+
     ^                                      ¦
     +--------------------------------------+

您可以為子組件傳遞一個回調函數,該函數接受兩個參數cellTopcellLeft 在子組件中,同時調用cellTopcellLeft值,這是在子組件中調用getMousePosition()函數。

在您的父組件中創建一個類似以下的函數:

handleSizeChange: function(cellTop, cellLeft){
    this.setState({
        cellTop: cellTop,
        cellLeft: cellLeft
    })
},

在您的Parent <Row>組件中,傳遞一個回調函數作為道具,如下所示:

<Row countRow={this.state.countRow}
     countCol={this.state.countCol}
     ref={(ref) => this.state}
     onSizeChange={this.handleSizeChange}
/>

在您的Child組件中,將this.props.handleSizeChange(top, left)添加到getMousePostion()函數中:

getMousePosition: function(element){

    let coordinates = element.target.getBoundingClientRect();
    let top = coordinates.top;
    let left = coordinates.left;

    this.setState({
        cellTop: top,
        cellLeft: left
    })

    this.props.handleSizeChange(top, left)
},

同樣的事實是,只要有可能,數據就最好從Parent -> Child組件中流出來,但是回調函數對於按鈕事件之類的東西是很常見的。 您可以使用Redux之類的東西來處理狀態管理,但這是相當先進的,如果這是一個簡單的初學者應用程序,則可能會過大。

另外,您應該對組件使用最新的React語法。 創建這樣的新類:

import React, { Component } from 'react'

class App extends Component {
      constructor() {
          super()

          //getinitialstate
          this.state = {
            cellTop: 0,
            cellLeft: 0
          }
      }
}

並定義這樣的類方法:

  componentWillMount() {
    // this runs right before the <App> is rendered

  })

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM