2017-11-14 15 views
4

私のアプリには親子コンポーネントがあります。私は子コンポーネントによって親コンポーネントの状態を更新したいが、動作していないようだ。私は長い間、Reactjsに取り組んできましたが、これは私にとって非常に奇妙です。ここでは親コンポーネントのための私のコードは次のとおりです。子の状態を親の状態で更新する必要があるときにthis.setStateが機能しない

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; 

そしてここでは、子コンポーネントのコードは次のとおりです。

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; 

今、親コンポーネントのgetCirclePoints方法では、私が子供からポイントを取得しますがthis.setState午前です働いていない。あなたもわかるように、私はthis.setStateコールバックに関数を渡しました。呼び出されず、空の配列にdataの状態も設定されています。私は最後の4時間この頭を叩いています。どんな種類の助けにも感謝します。私は愚かな間違いが私の側にないことを願っています。

+0

ログを取得する親のgetCirclePointsにポイントがありますか –

+0

'componentDidMount()の中に' this.state.points'を記録すると何が表示されますか –

+0

それは私にオブジェクトの配列を与えます。期待する。 –

答えて

2

では、あなたは状態がsetState()方法と直接だけ変更してはならないことを読み取ることができるドキュメントを反応します。あなたのコード内のrender方法は、少なくともと呼ばれているので

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

  1. processData中:

    data[i].weight /= 3; 
    
  2. renderであなたは直接、二回PorfolioMix状態を変更しました2回、this.state.dataになりますエラーにつながる空の配列あなたがここでエラーと実際の例を見ることができます

    :修正を

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

    ライブ例:https://jsfiddle.net/rhapLetv/1/それを修正するにはhttps://jsfiddle.net/rhapLetv/

    、あなたはprocessData方法でデータのコピーを返すことができます

    不変データを導入する有用なimmutable.js(または同様のライブラリ/ヘルパー)が見つかります。

0

processData()でも.bind(this)にする必要があります。これは、Reactのみがメソッド、コンストラクタ、およびコンポーネントのライフサイクルメソッドをレンダリングするために自動的にバインドされるためです。

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

これは問題ではありません。私はすでにそれを試みました。 –

関連する問題