React
父子组件的数据流向通常是由父组件通过props
传到子组件上,常规操作是父组件传入props
给子组件调用,例如:
function Child(props) {
return <div onClick={()=>props.handelClick}></div>;
}
class Parent extends React.Component {
constructor(props) {
super(props);
}
handelClick(e) {
alert(e);
}
render() {
const childProps={
handelClick= this.handelClick,
};
return (
<div>
<h1>Hello, world!</h1>
<Child {...childProps} />
</div>
);
}
}
ReactDOM.render(
<Parent />,
document.getElementById('root')
);
如上,父组件的handelClick
在子组件的点击事件触发时就会生效,通常我们的组件都可以使用这种方法去完成,但也有特例。
想象一个场景,子组件有一个查询输入框,回车会查询到一连串数据,点击这任一数据,会渲染父组件的页面,点击页面上的一个按钮,需要清空子组件的输入框查询数据。先想着数据从上而下来处理,那这个本该是子组件内部状态的输入数据,得是从props
传入子组件的,这样才能调用父组件的方法去修改值。但是实际操作过程会发现,父组件传入的value
值会使得我们无法再输入改变value
值,因为父组件没有改变props的值,这样我们还得在输入框监听onChange
事件,将修改的值实时回传(调用父组件修改value
方法)到父组件,然后再传入子组件更新输入框的内容。
有没有什么简单的方法呢,习惯vue
的人首先肯定会想到ref
操作,简单快捷。React
里也有ref
操作,我们看一下,该如何操作。
class Child extends React.Component {
constructor(props) {
super(props);
this.state={
value:"",
}
}
// 修改输入框的值
changeValue(e){
this.setState({
value: e.target.value
});
}
render(){
const { value } = this.state;
return (
<input value={value} onChange={()=>this.changeValue} />
)
}
}
class Parent extends React.Component {
constructor(props) {
super(props);
}
// 调用子组件方法清空子组件input输入框
clearInput(){
if(this.refInput){
const e = {
target: {
value: ""
}
};
this.refInput.changeValue(e);
}
}
render() {
return (
<div>
<h1>Hello, world!</h1>
<Child onRef={ref => {
this.refInput = ref;
}} />
<button onClick={()=>this.clearInput}>清除input数据</button>
</div>
)
}
}
ReactDOM.render(
<Parent />,
document.getElementById('root')
);
通过ref
可以得到子组件的所有方法和内部状态,看着是不是要比父子之间双向绑定简单很多,双向的话就是逻辑很清晰,始终保持着单向数据流的理念,我们具体使用还是要看项目情景。
网友评论