我有一个处于状态的对象,我想将此对象发送到子组件,并在更新对象后再次将其取回。我该怎么办?
这是父组件。
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>
);
}
}
答案 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。