传递对象作为反应中的组件的支柱

时间:2017-01-13 00:07:36

标签: reactjs

我有一个处于状态的对象,我想将此对象发送到子组件,并在更新对象后再次将其取回。我该怎么办?

这是父组件。

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

}

在子组件中,我收到道具作为对象,我用新值更新对象,然后将对象返回到回调函数。

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

}

1 个答案:

答案 0 :(得分:5)

孩子永远不应该改变它的道具,而且React中的数据流是一个向下的方式。

如果您的子组件想要向其父组件发送数据,您可以将回调函数传递给子组件,因此子组件可以通过该函数发回数据。

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。