React ref 基础使用、转发

应用场景:有时候我们需要拿到一个特定的元素,进行特定的操作。
当然我们可以用JS操作DOM通过id直接获取:

document.getElementById('input').setAttribute('style', 'color:blue');

但这样很麻烦啊,如果用JQuery还好说,不然的话可真是难受死了。
好在React提供了一种类似的方法:ref
基础使用:
1.创建ref
创建ref很简单,直接在React元素上声明属性即可:
基础的html组件和自定义组价都可以用哦。



这个ref就会被React发现,然后加入this.refs中。
2.使用ref
直接从this.refs中取出即可。
这里用console.log()打印出了this.refs的内容,你可以查看数据,就会发现我们已经拿到了ref实例:
注意:ref是在渲染时期创建的,所以要在挂载后使用:

componentDidMount() {
        console.log(this.refs);    
}

这样基础的ref创建和使用就完毕了。


接下来是高级部分:ref转发!
问题:如果我想将让父组件得到子组件的ref,由此控制具体的子元素怎么办?
由于React推荐单向数据流,所以让子组件创建一个ref,再传递给父组件,这样的方法是不推荐的,也得不到React很好的支持。
解决思路:父组件创建ref,向下传递给子组件。
正常人(我)的思路(行不通=-=):
父组件:

class Parent extends React.Component {
    constructor(props) { super(props); }
    render(){
        return (
            
        );
    }
}
ReactDOM.render(, document.getElementById('root'));

会警告:

 Warning: Child: `ref` is not a prop.

因为ref属于特殊属性,不会成为props的参数内容。
解决方法:
1.创建特殊的、专门用来传递ref的组件( 我觉得很麻烦哎,直接让我传不好嘛 ,不然设置refChile这种特殊特殊参数也好嘛):

//失去被ref权利的可怜的组件:
const Parent = React.forwardRef((props, ref) => (
    
));

可以看到,React.forwardRef把props和ref独立了出来,ref就作为参数存在啦.
2.创建特殊的ref:
特殊的组件配合特殊的ref创建方式:此处的ref需要用React.createRef()创建.

//创建特殊的自定义ref
const ref = React.createRef();

3.使用特殊的ref:
将ref做为值传递(奥利给!):

const inputRef = React.createRef();
class App extends React.Component {
    constructor(props) { super(props); }
    render() {
        return ();
                //请尝试比一下这个设置:
    }
    componentDidMount() {
        console.log(this.refs);
        console.log(inputRef);
    }
}

用console.log()打印的结果可以作为对比:

//console.log(this.refs);
{}
//console.log(inputRef);
{current: input}

可以看到特殊的ref也有特殊的读取方式。


补充:
React.forwardRef()组件只起传递作用,
ref='inputRef'就是传递字符串,使用这种声明方式,ref会被this.refs识别并保存,因此可以用this.refs来访问注册的子组件。
ref={inputRef}就是使用单独的ref变量来保存,因此单独通过inputRef变量来访问子组件。


可运行的代码(为自己准备的,万一下次忘了呢 ):

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';

const Parent = React.forwardRef((props, inputRef) => (
    
));

const inputRef = React.createRef();
class App extends React.Component {
    constructor(props) { super(props); }
    render() {
        //return ();
        return ();
    }
    componentDidMount() {
        console.log(this.refs);
        console.log(inputRef);
    }
}

ReactDOM.render(, document.getElementById('root'));

Ref转发本质:
ref转发并不是什么高深难懂的东西,它的原理有点白痴:

声明一个不能使用ref 的组件,那它就只能把ref当参数传递下去了。

太可怜了,有点因噎废食的感觉,那么问题来了:

如果我每层子组件都要ref,怎么办?!

你可能感兴趣的:(React ref 基础使用、转发)