2017-11-14 1 views
4

So habe ich eine Eltern- und eine Kindkomponente in meiner App. Ich möchte den Status der übergeordneten Komponente durch die untergeordnete Komponente aktualisieren, aber es scheint nicht zu funktionieren. Ich arbeite schon lange an Reactjs und das ist mir ziemlich fremd. Hier ist mein Code für die übergeordnete Komponente:this.setState funktioniert nicht, wenn der Status eines Elternteils von einem Kind aktualisiert werden muss

import React from 'react'; 
import { Stage } from 'react-konva'; 
import CircleComponent from './CircleComponent'; 
import LineComponent from './LineComponent'; 
import { getUserPlan } from '../../assets/UserPlan'; 
import { addColorClasses } from '../../helpers/utils'; 

class PortfolioMix extends React.Component { 
    constructor(props) { 
    super(props); 

    const data = addColorClasses(getUserPlan().plans[0]); 

    this.state = { 
     data: data, 
     circlePoints: [] 
    }; 

    this.getCirclePoints = this.getCirclePoints.bind(this); 
    } 

    getCirclePoints(points) { 
    this.setState({ 
     circlePoints: points, 
     word: 'hello' 
    },() => { console.log(this.state); }); 
    } 

    processData() { 
    let data = this.state.data; 

    if(data[0].weight > 0.25 || (data[0].weight+data[1].weight) > 0.67) { 
     for(let i = 0; i < data.length; i++) { 
     data[i].weight /= 3; 
     } 
    } 

    return data; 
    } 

    render() { 
    const processedData = this.processData(); 
    const firstCircle = processedData.splice(0,1); 
    const pmData = processedData.splice(0,this.state.data.length); 

    return(
     <div> 
     <Stage 
      height={800} 
      width={1200} 
      style={{ backgroundColor: '#fff'}}> 
      <CircleComponent 
      x={1200/2} 
      y={800/2} 
      outerRadius={firstCircle[0].weight*1200} 
      outerColor={firstCircle[0].outerColor} 
      innerRadius={firstCircle[0].weight*1200*0.3} 
      innerColor={firstCircle[0].innerColor} 
      shadowColor={firstCircle[0].innerColor} 
      getCirclePoints={this.getCirclePoints} 
      /> 
     </Stage> 
     </div> 
    ); 
    } 
} 

export default PortfolioMix; 

Und hier ist der Code des Kindes Komponente:

class CircleComponent extends React.Component { 
    constructor(props) { 
    super(props); 

    this.state = { 
     points: this.getPoints(), 
    }; 
    } 

    componentDidMount() { 
    this.props.getCirclePoints(this.state.points); 
    } 

    getPoints() { 
    const radius = this.props.outerRadius; 
    const x = this.props.x; 
    const y = this.props.y; 

    const points = []; 
    let angle = 0; 

    for(let i = 0; i < 8; i++) { 
     points.push({ 
     pointX: x + radius * Math.cos(-angle * Math.PI/180), 
     pointY: y + radius * Math.sin(-angle * Math.PI/180) 
     }); 
     angle += 42.5; 
    } 

    return points; 
    } 

    render() { 
    const { 
     x, 
     y, 
     outerRadius, 
     outerColor, 
     shadowColor, 
     innerRadius, 
     innerColor 
    } = this.props; 

    return (
     <Layer> 
     <Group> 
      <Circle 
      x={x} 
      y={y} 
      radius={outerRadius} 
      fill={outerColor} 
      shadowBlur={5} 
      shadowColor={shadowColor} 
      /> 
      <Circle 
      x={x} 
      y={y} 
      radius={innerRadius} 
      fill={innerColor} 
      /> 
     </Group> 
     </Layer> 
    ); 
    } 
} 

CircleComponent.propTypes = { 
    x: propTypes.number.isRequired, 
    y: propTypes.number.isRequired, 
    outerRadius: propTypes.number.isRequired, 
    outerColor: propTypes.string.isRequired, 
    shadowColor: propTypes.string, 
    innerRadius: propTypes.number.isRequired, 
    innerColor: propTypes.string.isRequired, 
    getCirclePoints: propTypes.func 
}; 

export default CircleComponent; 

nun in getCirclePoints Methode der Eltern-Komponente, erhalte ich die Punkte von dem Kind aber this.setState ist funktioniert nicht. Wie Sie sehen können, habe ich auch eine Funktion an this.setState Callback übergeben, es wird nicht aufgerufen und auch setzen data Zustand auf ein leeres Array. Ich habe mir in den letzten 4 Stunden den Kopf gestoßen. Jede Art von Hilfe wird geschätzt. Ich hoffe, es gibt keinen dummen Fehler auf meiner Seite.

+0

Sie einen Fehler sehen Sie, ist es, Punkte in 'getCirclePoints' von Eltern –

+0

angemeldet zu werden, was es, wenn Sie' this.state.points' innen log besagen 'componentDidMount()' –

+0

Es ist mir ein Array von Objekten, wie ich gibt erwarten von. –

Antwort

2

In React docs können Sie lesen, dass nicht direkt geändert werden, sondern nur mit der setState() Methode der Staat sollte. Sie haben direkt PorfolioMix Zustand ändern zweimal:

  1. in processData:

    data[i].weight /= 3; 
    
  2. in render:

    const processedData = this.processData(); 
    const firstCircle = processedData.splice(0,1); 
    const pmData = processedData.splice(0,this.state.data.length); 
    

Da die render Methode in Ihrem Code zumindest genannt wird zweimal wird this.state.data sein ein leeres Array, das zu einem Fehler führt.

Sie können ein anschauliches Beispiel mit dem Fehler sehen hier: https://jsfiddle.net/rhapLetv/

es zu beheben, können Sie eine Kopie der Daten in der processData Methode zurückgeben können:

processData() { 
    const data = this.state.data; 

    if(data[0].weight > 0.25 || (data[0].weight+data[1].weight) > 0.67) { 
    return data.map(point => ({ ...point, weight: point.weight/3 })) 
    } else { 
    return data.slice() 
    } 
} 

Live-Beispiel mit Korrekturen: https://jsfiddle.net/rhapLetv/1/

Sie können nützliche immutable.js (oder ähnliche Bibliotheken/Helfer) finden, die unveränderliche Daten einführt.

0

Sie müssen .bind(this) bei Methode processData() auch, weil React nur automatisch binden (this), um Methode, Konstruktor und Komponenten Lebenszyklen Methoden zu rendern.

class PortfolioMix extends React.Component { 
    constructor(props) { 
    super(props); 

    const data = addColorClasses(getUserPlan().plans[0]); 

    this.state = { 
     data: data, 
     circlePoints: [] 
    }; 

    this.getCirclePoints = this.getCirclePoints.bind(this); 
    this.processData = this.processData.bind(this); 
    } 
// ... 
+0

Das ist nicht das Problem. Das habe ich schon probiert. –

Verwandte Themen