在React当中,function组件返回的是一段jsx代码,对于function组件本身来说,是没有实例的,因此如果我们在引用一个function组件时如果设置了一个ref属性是无效的,React还会做出一些检查并给出错误提示,例如:
<div id="root"></div> <script type="text/babel"> function MyComponent(props){ //MyComponent是一个函数组件 return <input type="text"/> } class App extends React.Component{ ref = React.createRef(); componentDidMount(){ console.log(this.ref.current) //挂载完成后打印this.ref.current } render(){ return <div><MyComponent ref={this.ref}/></div> //引用函数组件时使用ref尝试获取该函数组件实例 } } ReactDOM.render(<App/>,root) </script>
执行后控制台输出如下:
意思就是对于function组件来说,不能给他直接给他设置ref,另外打印出来的也是null
对于function组件来说,我们可以用React.forwardRef()来实现,具体的做法是把function组件作为参数传递给React.forwardRef(),然后function组件可以带两个参数,分别是props和ref,在function组件内部返回的jsx中可以给某个DOM节点或自组件设置ref属性,值就是这个函数组件的参数二,例如:
function myComponent(props,refObj){
return <div>
<p ref={refObj}>123</p> //这里refObj就是传入的参数2了
</div>
}
举个栗子,和上一节的几个ref例子实现的效果一样,我们用函数组件也实现一个类似的效果,如下:
<div id="root"></div> <script type="text/babel"> const MyComponent = React.forwardRef((props,ref)=>( //传递了一个props和ref属性,我们先用props进行初始化 <p ref={ref}>no:{props.no}</p> )) class App extends React.Component{ state = {no:1} domp = React.createRef(); test= ()=>{ this.domp.current.textContent = 'no:'+ ++this.state.no } //之后点击测试按钮后就修改MyComponent组件内p元素的textContent render(){ return <div> <button onClick={this.test}>测试</button> <MyComponent no={this.state.no} ref={this.domp}/> //这里指定ref属性为this.ref,之后就可以通过this.domp来访问MyComponent组件内的p节点对象了 </div> } } ReactDOM.render(<App/>,root) </script>
writer by:大沙漠 QQ:22969969
效果和上一节的是一样的,就不演示了,我们这里使用了props传值进行初始化,之后点击测试按钮时就同构this.domp获取到MyComponent组件内的p元素实例,然后通过原生的textContent属性设置其文本内容。