繁体   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