父子组件数据传递方式:
1.通过props
2.通过innerHTML(this.props.children),当期望在父组件中通过子组件的实例DOM传递一些静态的DOM节点或innerHTML的时候可以使用
react数据单向流:子父组件之间的通讯(数据传递)规则,原则:数据只能从父组件传递到子组件,而不能由子组件直接修改父组件的数据,数据属于谁谁才有资格去修改;
所以子组件想要修改父组件数据的话,最好通知给父组件让父组件进行修改,在下面代码示例中,单行文本框input被设置了初始默认value值,而这个值是由父组件传递过来的,此时该表单的value值受组件控制住了,称为受控组件;同时如果没有为这个表单组件绑定changge事件则会报错,这时,就需要子组件更新父组件状态了,需要父组件传递回调函数到子组件中,子组件调用,回调函数中接收该表单的value值进行数据修改
<body>
<div id="root"></div>
<script type="text/babel">
class Myinput extends React.Component{
render(){
var {type = "text", place, value} = this.props;
this.handleChange = this.handleChange.bind(this);
return <p><input ref="focusInput" type={type} placeholder={place} value={value} onChange={this.handleChange}/></p>
}
handleChange(e){
this.props.onchange(e.target.value);
}
handleFocus(){
console.log(this.refs)
this.refs.focusInput.focus();//获取ref=focusInput的真实DOM元素,执行获取焦点(操作DOM)
}
componentDidMount(){
if(this.props.focus){//如果该实例focus为true,就执行handleFocus
this.handleFocus();
}
}
}
class Wrap extends React.Component{
constructor(){
super();
this.textChange = this.textChange.bind(this);
this.pwdChange = this.pwdChange.bind(this);
this.handleSbt = this.handleSbt.bind(this);
this.checkChange = this.checkChange.bind(this);
this.state = {
phone: "15348298177",
remember: true
}
}
render(){
return (
<div>
<Myinput value= {this.state.phone} place="请输入手机号" οnchange={this.textChange}></Myinput>
<Myinput focus={true} type= "password" place="请输入密码" οnchange={this.pwdChange}></Myinput>
<p><input type="checkbox" onChange={this.checkChange} checked={this.state.remember}/></p>
<button onClick={this.handleSbt}>登录</button>
</div>
)
}
textChange(val){
this.setState({phone: val});
}
pwdChange(val){
this.setState({pwd: val});
}
handleSbt(){
console.log(this.state);
//处理提交。。。
}
checkChange(e){
// console.log(e.target.checked === !this.state.remember) //true
// this.setState({remember: e.target.checked})
this.setState((pre) => ({remember: !pre.remember}));
}
}
ReactDOM.render(<Wrap></Wrap>, document.querySelector("#root"))
</script>
</body>
输入后点击登录:
再说一下refs,下面有一些正好使用 refs 的场景:
- 处理focus、文本选择或者媒体播放
- 触发强制动画
- 集成第三方DOM库
如果可以通过声明式实现,就尽量避免使用 refs 。
ref属性也可以传递一个函数,函数的第一个参数是默认就是当前的DOM节点,在函数内可以自定义一个属性,比如:
ref=(input=>this.focusInput=input)
然后就可以将上面 this.refs.focusInput.focus()换成this.focusInput.focus()