2017-01-13 37 views
0

私は状態にあるオブジェクトを持っていますが、このオブジェクトを子コンポーネントに送り、オブジェクトを更新した後に再び取得したいと考えています。反応中のコンポーネントの小道具としてオブジェクトを渡す

これは親コンポーネントです。

class TextN extends React.Component { 

constructor(props){ 
    console.log('Text constructor called'); 
    super(props); 
    this.state = { 
    w:'auto', 
    h:'auto', 
    widthF:32, 
    heightF:23, 
    rightClick:false, 
    textObj:{ 
     modalShow: false, 
     message: 'Text', 
     textPosY:5, 
     textPosX:5, 
     degreeOfRot:0, 
     maxNumberOfChar:0, 
     fontSize: 15, 
     fontWeight:'bold', 
     fontfamily:'arial', 
    }, 
    } 
} 

onDrag(e,ui){ 
    console.log(e); 
    console.log(ui); 
} 

onDragStop(e,ui){ 
    console.log(e); 
    console.log(ui); 
} 

editText(){ 
    var tObj = this.state.textObj; 
    tObj.modalShow = true; 
    this.setState({ textObj: tObj }); 
} 

getData(dataText){ 
    var tObj = this.state.textObj; 
    tObj.modalShow =false; 
    tObj.message = dataText; 
    this.setState({ textObj: tObj }); 
} 


render() { 
    var style = { 

     titleText:{ 
      fontFamily:this.state.textObj.fontfamily, 
      fontSize:this.state.textObj.fontSize, 
      fontWeight:this.state.textObj.fontWeight, 
     }, 
    } 
    return (
     <Rnd ref={c => { this.rnd = c; }} 
     initial={{ 
      x: this.state.textObj.textPosX, 
      y: this.state.textObj.textPosY, 
      width: this.state.w, 
      height: this.state.h, 
     }} 
     style={style1} 
     minWidth={this.state.widthF} 
     minHeight={this.state.heightF} 
     maxWidth={500} 
     maxHeight={500} 
     bounds={'parent'} 
     //onDrag={this.onDrag.bind(this)} 
     onDragStop={this.onDragStop.bind(this)} 
     isResizable={{top:false, right:true, bottom:false, left:false, topRight:false, bottomRight:false, bottomLeft:false, topLeft:false}} 
     > 
     <label style={style.titleText} onClick={this.editText.bind(this)}>{this.state.textObj.message}</label> 
     **<TModal show={this.state.textObj} callBack={this.getData.bind(this)}/>** 
     </Rnd> 
    ) 
} 

}

そして私は新しい値でオブジェクトを更新し、Iは、コールバック関数にオブジェクトを返すオブジェクトとして小道具を受け取る子コンポーネントです。

class TextModal extends React.Component{ 
constructor(props) { 
    console.log('Modal constructor called'); 
    super(props); 
    this.state = { 
     showMod: this.props.show.modalShow, 
     text:'Text', 
     fontModal:false, 
     fontObject:{}, 
     textObj:{}, 
     displayColorPicker:false, 
     color: { 
     r: '241', 
     g: '112', 
     b: '19', 
     a: '1', 
    }, 
    }; 
    } 

componentWillReceiveProps(nextProps){ 
    console.log('inside components will recieve'); 
    this.setState({showMod : this.props.show.modalShow}); 
    this.setState({text:this.props.show.message}); 
    this.setState({textObj:this.props.show}); 
    console.log(this.props.show); 
} 

shouldComponentUpdate(nextProps, nextState){ 
    if(this.state.showMod !== nextState.showMod){ 

     return true; 

    }else if(this.state.fontModal !== nextState.fontModal){ 

     return true; 

    }else if(this.state.displayColorPicker !== nextState.displayColorPicker){ 

     return true; 

    }else if(this.state.color !== nextState.color){ 

     return true; 

    }else if(this.state.text !== nextState.text){ 

     return true; 
    } 

    return false; 

} 



onSubmit(e){ 
    this.props.callBack(this.state.textObj); 
} 

close() { 
    console.log('close is called'); 
    this.setState({ showMod: false }); 
    this.setState({fontModal:false}); 
} 



handleChange(e){ 
    this.setState({text:e.target.value}); 
} 





render(){ 

    return(
     <div> 
     <Modal show={this.state.showMod} onHide={this.close.bind(this)}> 
      <Modal.Header style={{textAlign:'center'}}> 
       <Modal.Title>Text</Modal.Title> 
      </Modal.Header> 
      <Modal.Body style={{textAlign:'center'}}> 
      <form> 
      <label>Text:</label><input type="text" ref={(c) => this.title = c} name="title" onChange={this.handleChange.bind(this)} value={this.state.text}/><br /> 
      <label>Current Left Position:</label><input type="number" value={this.state.textObj.textPosX}/><br /> 
      <label>Current Top Position:</label><input type="number" value={this.state.textObj.textPosY}/><br /> 
      <label>Degree of Rotation:</label><input type="number" value={this.state.textObj.degreeOfRot}/><br /> 
      <label>Max # of Characters:</label><input type="number" value={this.state.textObj.maxNumberOfChar}/><br /> 
      <label>Click to select Font:</label><input style={{fontFamily:this.state.fontObject.fontFamily,fontWeight:this.state.fontObject.fontStyle}} value={this.state.fontObject.fontFamily} onClick={this.showFontModal.bind(this)}/><br /> 
      <label>Click to select Color:</label><input style={{backgroundColor:styles.color.background}} onClick={this.handleColorPicker.bind(this)}/><br /> 
      </form> 
      { this.state.displayColorPicker ? <div style={ styles.popover }> 
      <div style={ styles.cover } onClick={ this.handleColorClose.bind(this) }/> 
       <SketchPicker color={ this.state.color } onChange={ this.handleChangeColor.bind(this) } /> 
      </div> : null } 
      </Modal.Body> 
      <Modal.Footer> 
       <Button bsStyle="primary" bsSize="small" onClick={this.onSubmit.bind(this)}>Ok</Button> 
       <Button bsStyle="warning" bsSize="small" onClick={this.close.bind(this)}>Close</Button> 
      </Modal.Footer> 
     </Modal> 
     </div> 
    ); 
} 

}

+0

あなたの状態を管理するためにreduxのようなものを使用していますか、またはアプリケーションレベルで自分自身で何らかの状態オブジェクトを管理するだけですか? – kinakuta

+0

私はreduxを使用していません私は自分の状態を管理しています。 – Vasista

+0

おそらく、親コンポーネントのメソッドを定義し、それらを子コンポーネントに渡します。 1つのメソッドは、子コンポーネントに持たせたい状態の値を返し、もう1つは適切な値と更新状態を取ります。親コンポーネントのインスタンス上のメソッド内でこれらのロジックをカプセル化し、それらを小道具として子に渡します。 – kinakuta

答えて

5

子は、その小道具を変異させるべきではありません、して反応におけるデータフローは、ダウン一つの方法です。

子コンポーネントが親にデータを送信する場合は、子コンポーネントにコールバック関数を渡すことができるため、子コンポーネントは関数を介してデータを返すことができます。

class Parent extends React.Component { 
    cb (dataFromChild) { 
    console.log(dataFromChild) // 100 
    } 

    render() { 
    return <Child cb={this.cb} someData={99} /> 
    } 
} 

class Child extends React.Component { 
    componentDidMount() { 
    this.props.cb(this.props.someData + 1) 
    } 

    render() { 
    return <h1>Child</h1> 
    } 
} 

アプリケーションが複雑になると、ReduxやMobXなどの状態管理ソリューションを使用することになります。

+0

私はプログラムで私の質問を編集しました。私はfutureでreduxを使うことを考えましたが、これは私が達成しようとしているPOCであり、今のところこれだけ多く必要です。 @CodinCat – Vasista

+0

あなたのコードはうまく見えますが、今は何が問題なのですか?それが動作しない場合、私は完全なコードを参照する必要があります – CodinCat

+0

それは私にこのエラーを与える。 "invariant.js:44キャッチ不変不変違反:オブジェクトがリアクションの子として有効ではありません"。私は今完全なコードを追加しました。 – Vasista

関連する問題