2017-07-09 22 views
0

私は今接触しています子供から親に状態を取得する方法

私は2つのコンポーネントを持っています。親Square、子供。

私はsetValues cellTopcellLeftをから親にして使いたいと思っています。

どうすればいいですか?

私のコードは、私はすべてのコンポーネントの状態を使用しないように、あなたをお勧めします怒鳴る

var Square = React.createClass({ 
 

 

 
\t getInitialState: function() { 
 

 
\t \t return { 
 

 
\t \t countRow: 4, 
 
\t \t countCol: 4, 
 
\t \t mouseOnTable: false, 
 
\t \t onDelRow: false, 
 
\t \t onDelCol: false 
 

 
\t \t } 
 

 
\t }, 
 

 

 
\t appendCol: function() { 
 

 
\t \t var countColNew = this.state.countCol + 1; 
 

 
\t \t this.setState({countCol: countColNew}); //change initiale state "countCol" (add new column) 
 

 
\t \t //console.log(this.state.countCol) 
 

 
\t }, 
 

 
\t appendRow: function() { 
 

 
\t \t var countRowNew = this.state.countRow + 1; 
 

 
\t \t this.setState({countRow: countRowNew}); //change initiale state "countRow" (add new row) 
 

 
\t \t //console.log(this.state.countRow) 
 

 
\t }, 
 

 
\t deleteCol: function() { 
 

 
\t \t var countColNew = this.state.countCol - 1; 
 

 
\t \t this.setState({countCol: countColNew}); //change initiale state "countCol" (delete col) 
 

 
\t \t //console.log(this.state.countCol) 
 

 
\t }, 
 

 
\t deleteRow: function() { 
 

 
\t \t var countRowNew = this.state.countRow - 1; 
 

 
\t \t this.setState({countRow: countRowNew}); //change initiale state (delete row) 
 

 
\t \t //console.log(this.state.countRow) 
 

 
\t }, 
 

 

 
\t hiddenButtons: function(){ 
 
\t \t var mouseOnTableNew = true; 
 
\t \t this.setState({mouseOnTable: mouseOnTableNew}) 
 
\t }, 
 

 

 
\t showButtons: function(){ 
 
\t \t var mouseOnTableNew = false; 
 
\t \t this.setState({mouseOnTable: mouseOnTableNew}) 
 
\t }, 
 

 

 

 
\t render: function() { 
 

 
\t \t var timeOut; 
 

 

 
\t \t return (
 

 
\t \t \t <div className='square'> 
 

 
\t \t \t \t <table className='square__table' 
 
\t \t \t \t \t \t onMouseOver={this.hiddenButtons} \t \t \t \t \t \t \t \t \t \t \t \t \t \t \t 
 
\t \t \t \t \t \t onMouseLeave={() => {timeOut=setTimeout(this.showButtons,200)}}> 
 

 

 
\t \t \t \t \t \t \t <Row countRow={this.state.countRow} 
 
\t \t \t \t \t \t \t \t countCol={this.state.countCol} 
 
\t \t \t \t \t \t \t \t ref={(ref) => this.state} 
 

 
\t \t \t \t \t \t \t \t /> \t \t 
 

 

 
\t \t \t \t </table> 
 

 

 
\t \t \t \t \t \t \t <button className="square__button square__button_append square__button_col-append" 
 
\t \t \t \t \t \t \t \t \t onClick={this.appendCol}> 
 
\t \t \t \t \t \t \t </button> 
 

 

 
\t \t \t \t \t   <button className="square__button square__button_delete square__button_col-delete" 
 
\t \t \t \t \t   \t \t style={this.state.countCol===1 || 
 
\t \t \t \t \t   \t \t \t this.state.mouseOnTable===false || 
 
\t \t \t \t \t   \t \t \t this.state.onDelRow===true ? {visibility: "hidden"} : {visibility: "visible"}} 
 

 
\t \t \t \t \t   \t \t onClick={this.deleteCol} 
 
\t \t \t \t \t   \t \t onMouseOver={() => {clearTimeout(timeOut); 
 
\t \t \t \t \t   \t \t \t \t \t \t \t this.setState({onDelCol:true})}} 
 
\t \t \t \t \t   \t \t onMouseLeave={() => {this.setState({onDelCol:false})}}> 
 
\t \t \t \t \t   </button> 
 

 

 
\t \t \t \t \t   <button className="square__button square__button_append square__button_row-append" 
 
\t \t \t \t \t   \t \t onClick={this.appendRow}> 
 
\t \t \t \t \t   </button> 
 

 

 
\t \t \t \t \t   <button className="square__button square__button_delete square__button_row-delete" 
 
\t \t \t \t \t   \t \t style={this.state.countRow===1 || 
 
\t \t \t \t \t   \t \t \t this.state.mouseOnTable===false || 
 
\t \t \t \t \t   \t \t \t this.state.onDelCol===true ? {visibility: "hidden"} : {visibility: "visible"}} 
 

 
\t \t \t \t \t   \t \t onClick={this.deleteRow} 
 

 
\t \t \t \t \t   \t \t onMouseOver={() => {clearTimeout(timeOut); 
 
\t \t \t \t \t   \t \t \t \t \t \t \t this.setState({onDelRow:true})}} 
 

 
\t \t \t \t \t   \t \t onMouseLeave={() => {this.setState({onDelRow:false})}}> 
 
\t \t \t \t \t   </button> 
 

 

 

 
\t \t \t \t 
 

 
\t \t \t </div> 
 

 

 
\t \t) 
 

 
\t } 
 

 
}) 
 

 

 
//================================================== 
 

 

 
var Row = React.createClass({ 
 

 

 

 
\t getInitialState: function(){ 
 
\t \t return { 
 

 
\t \t \t cellTop: 0, 
 
\t \t \t cellLeft: 0, 
 

 
\t \t } 
 

 

 
\t }, 
 

 

 

 
\t createCol: function() { 
 

 
\t \t var columns = []; 
 

 
\t \t for(let i = 0; i < this.props.countCol; i++){ 
 
\t \t \t columns.push(this.createCell) 
 
\t \t } 
 

 
\t \t return columns; 
 

 

 
\t }, 
 

 

 

 
\t createRow: function (k) { 
 

 
\t \t return (
 

 
\t \t \t <tr key={k}> 
 
\t \t \t \t {this.createCol().map(function(cell,key){ 
 
\t \t \t \t \t return (
 
\t \t \t \t \t \t \t cell(key) 
 
\t \t \t \t \t \t) 
 
\t \t \t \t })} 
 
\t \t \t </tr> 
 
\t \t) 
 
\t }, 
 

 

 

 
\t createCell: function(k){ 
 

 
\t \t return (
 

 
\t \t \t <td key={k}> 
 
\t \t \t \t <div className="square__cell" onMouseOver={this.getMousePosition}></div> 
 
\t \t \t </td> 
 
\t \t) 
 

 
\t }, 
 

 

 
\t getMousePosition: function(element){ 
 

 
\t \t let coordinates = element.target.getBoundingClientRect(); 
 
\t \t let top = coordinates.top; 
 
\t \t let left = coordinates.left; 
 
\t \t 
 
\t \t this.setState({ 
 
\t \t \t cellTop: top, 
 
\t \t \t cellLeft: left 
 
\t \t }) 
 

 

 
\t }, 
 

 

 

 
\t render: function(){ 
 

 
\t \t \t var lines = [] 
 
\t \t \t for (let i = 0; i < this.props.countRow; i++) { 
 
\t \t \t lines.push(this.createRow(i)) 
 
\t \t } 
 

 

 
\t \t return (
 

 
\t \t \t <tbody> \t \t 
 
\t \t \t \t {lines} 
 
\t \t \t </tbody> 
 
\t \t) 
 
\t } 
 

 

 

 
})

+1

、あなたは親 – OverCoder

+0

にチャイルズ、ないチャイルズに親からのデータを渡すことができ、私は宣言することができますこれは親の状態を子供から動的に変えますか? –

+1

いいえ、別の方向から考える必要があります。親が行をカスタマイズし、行が親をカスタマイズしないようにします。たとえば、行のサイズに基づいて親のサイズを変更する場合は、行を親のサイズでサイズ変更します。 – OverCoder

答えて

1

子コンポーネントには、2つの引数cellTopcellLeftを受け入れるコールバック関数を渡すことができます。あなたの子コンポーネントでは、cellTopcellLeftの値を同時に渡して、子コンポーネントにgetMousePosition()関数を呼び出しています。あなたの親コンポーネントで

このような関数を作成:あなたの親<Row>コンポーネントで

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

をこのような小道具としてコールバック関数を渡す:あなたの子コンポーネントで

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

はに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 

    }) 
+0

既にあなたが書いたようなものがありました。 また、あなたの方法でこれがどのように機能するのかを詳しく解説します。 ご協力いただきありがとうございます! –

1

です。これは、親コンポーネントを子から制御したいときには問題になります。

代わりに、

  • は、外部オブジェクト(店舗)
  • に小道具
  • 移動状態と、すべてのデータを介してデータを受信するすべてのコンポーネントデータが
  • を変更した場合、ストアは、あなたのコンポーネントをアップデートする作りますちょうどアップデートストアのコンポーネントから

をご覧ください。https://github.com/reflux/refluxjs

+---------+  +--------+  +-----------------+ 
¦ Actions ¦------>¦ Stores ¦------>¦ View Components ¦ 
+---------+  +--------+  +-----------------+ 
    ^         ¦ 
    +--------------------------------------+ 
関連する問題