2017-07-09 2 views
0

Ich bin neu in ReactWie bekomme ich den Status von Kind zu Eltern reagieren

Ich habe zwei Komponenten. Elternteil Square, Kind .

Ich möchte SetValues ​​cellTop und cellLeft von zu Eltern und verwenden Sie es.

Wie kann ich es tun.

Mein Code ist unten

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

Daten nur eine Richtung fließt in, können Sie Daten von den Eltern auf Childs passieren kann, nicht Childs Mutter – OverCoder

+0

Kann ich erklären Dies gibt in Eltern und ändert es dynamisch von Kind? –

+1

Nein. Sie müssen es aus einer anderen Richtung denken. Passen Sie die übergeordnete Zeile an die übergeordneten Elemente an, nicht die Zeilen, um die übergeordneten Elemente anzupassen. Wenn Sie beispielsweise die Größe Ihres übergeordneten Elements anhand Ihrer Zeilengröße ändern, ändern Sie die Größe der Zeilen für die übergeordnete Größe. – OverCoder

Antwort

1

Sie können Ihr Kind Komponente eine Callback-Funktion übergeben, die zwei Argumente akzeptiert, cellTop und cellLeft. Geben Sie in Ihrer untergeordneten Komponente die Werte cellTop und cellLeft zur gleichen Zeit ein, zu der Sie die Funktion getMousePosition() in Ihrer untergeordneten Komponente aufrufen.

In Ihrer Eltern Komponente Erstellen Sie eine Funktion wie folgt aus:

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

In Ihrer Eltern <Row> Komponente eine Callback-Funktion als Stütze wie dies passieren:

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

in Ihrem Kind Komponente hinzufügen this.props.handleSizeChange(top, left) zu Ihre getMousePostion() Funktion:

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) 
}, 

Es ist auch wahr, dass, wann immer es möglich ist, es am besten ist, wenn Daten von Parent ->Child Komponenten fließen, aber Callback-Funktionen sind für Dinge wie Knopf-Ereignisse üblich. Sie könnten etwas wie Redux verwenden, um die Zustandsverwaltung zu handhaben, aber das ist ziemlich fortgeschritten und ist wahrscheinlich zuviel, wenn es sich um eine einfache Anfängeranwendung handelt.

Außerdem sollten Sie die neueste React-Syntax für Komponenten verwenden.Erstellen Sie neue Klassen wie folgt aus:

import React, { Component } from 'react' 

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

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

und definieren Klassenmethoden wie folgt aus:

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

    }) 
+0

Schon hat etwas wie du geschrieben und es funktioniert jetzt. Auch jetzt lesen Sie detaillierter, wie es auf Ihre Art funktioniert! Danke für Ihre Hilfe! –

1

Ich würde Ihnen empfehlen, nicht zu Zustand in Komponenten zu verwenden. Dies führt nur zu Problemen, wenn Sie die Elternkomponente von Kind steuern möchten.

Stattdessen

  • machen alle Komponenten Daten über Requisiten erhalten
  • Bewegungszustand und alle Daten in externen Objekt (store)
  • der Laden Sie Ihre Komponenten machen aktualisieren, wenn die Daten
  • ändert von den Bestandteilen aktualisieren Sie einfach Speicher

Betrachten Sie https://github.com/reflux/refluxjs

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