Dans le flux de données typique de React, le props
passage est le seul moyen pour les composants parent-enfant d'interagir ; en passant une nouvelle props
valeur, le composant enfant est re-, réalisant ainsi la communication entre les composants parent-enfant. Bien sûr, comme décrit sur le site officiel de React, en plus du volume de données typique de React, dans certains cas (comme l'intégration avec une bibliothèque dom tierce, ou la concentration sur un certain élément dom, etc.), nous pouvons avoir besoin pour modifier les sous-composants. Dans un sens, c'est la méthode re-render
. ref
fourni par React, ref
représente une référence à l'instance réelle du composant, qui est en fait ReactDOM.render()返回的组件实例
; être distingué, >Lors du rendu d'un composant, l'instance du composant est renvoyée ; lors du rendu d'un élément dom, un nœud dom spécifique est renvoyé. ReactDOM.render()
const domCom = <button>button</button>; const refDom = ReactDOM.render(domCom,container); //ConfirmPass的组件内容省略 const refCom = ReactDOM.render(<confirmpass></confirmpass>,container); console.log(refDom); console.log(refCom);Le code ci-dessus renvoie le résultat de la console comme indiqué ci-dessous :
peut être accroché à Sur n'importe quel composant, il peut être accroché au composant ou à l'élément dom ; la différence entre les deux est la même que la réponse dans l'image ci-dessus : ref
Accroché au composant ( ici, le composant fait référence au composant avec état) Ref représente une référence à une instance de composant et, lorsqu'il est monté sur un élément dom, représente un nœud d'élément dom spécifique.ref peut être défini sur une fonction de rappel L'attribut ref peut être défini sur une fonction de rappel, ce qui est également l'utilisation officiellement recommandée. Le moment de l'exécution de cette fonction est :
, la fonction de rappel est exécutée immédiatement et le paramètre de la fonction de rappel est l'instance spécifique du composant.
组件被挂载后
, le rappel sera également exécuté immédiatement. À ce moment, le paramètre de la fonction de rappel est
组件被卸载或者原有的ref属性本身发生变化时
pour garantir les fuites de mémoire.null
tutoriel React"
Par exemple, le code suivant :RegisterStepTwo = React.createClass({ getInitialState(){ return {visible: true}; }, changeVisible(){ this.setState({visible: !this.state.visible}); }, refCb(instance){ console.log(instance); }, render(){ return( <p> <button>{this.state.visible ? '卸载' : '挂载'}ConfirmPass </button> { this.state.visible ? <confirmpass></confirmpass>: null } </p> ) } });Le code ci-dessus peut être rendu sur la page On constate que console.log génère l'instance de composant correspondante lorsque le bouton est commuté,
bascule également entre le montage et le démontage, afin que vous puissiez voir différents résultats de console.log. ConfirmPass
définit la valeur de ref sur une chaîne. input
<input>Ensuite, l'instance du composant est accessible via
à d'autres endroits tels que les rappels d'événements, qui est en fait le nœud de l'élément dom. this.refs.input
let inputEl = this.refs.input; //然后通过inputEl来完成后续的逻辑,如focus、获取其值等等Obtenez le nœud dom correspondant au composant référencé par refPeu importe que la valeur du paramètre ref soit une fonction de rappel ou une chaîne, vous pouvez utiliser
pour obtenir le vrai nœud dom une fois le composant monté. ReactDOM.findDOMNode(ref)
pour l'obtenir. Cette méthode est souvent utilisée pour la référence sur les composants React. . ReactDOM.findDOMNode(ref)
Lors de l'utilisation de composants avec état de réaction, ref fait référence à l'instance du composant afin qu'il puisse être transmis via le sous-composant peut accéder à ref
, ref
, props
, aux méthodes d'instance (méthodes non héritées), etc. des instances de sous-composants. state
refs
L'utilisation de ref pour accéder aux sous-composants peut être dans les cas suivants :
- Accéder à un nœud DOM spécifique du sous-composant pour compléter une certaine logique, qui est complétée via
- , comme la question soulevée par le questionneur sur segmentfault.
this.refs.childComponentRefName.refs.someDomRefName
Vous pouvez accéder aux méthodes d'instance publique des sous-composants pour compléter certaines logiques écrites. Par exemple, un sous-composant définit une méthode - pour réinitialiser la valeur de l'élément de formulaire du sous-composant. À ce stade, le composant parent peut utiliser
pour terminer la réinitialisation de l'élément de formulaire du sous-composant.
reset
this.refs.childComponentRefName.reset()
... - Mais cela dit, React ne recommande pas d'accéder directement à la méthode d'instance du composant enfant dans le composant parent pour En complétant une certaine logique, dans la plupart des cas, il sera plus clair d'utiliser la méthode standard de flux de données de réaction
De plus, dans le cas ci-dessus, lorsque la relation entre les composants est profondément imbriquée, cette méthode apparaîtra extrêmement moche.
ref在无状态组件中的使用
上文说到的react组件都是指有状态的,对于无状态组件stateless component
而言,正如这篇文章React创建组件的三种方式及其区别里描述的一样,无状态组件是不会被实例化的,在父组件中通过ref
来获取无状态子组件时,其值为null
,所以:
无法通过
ref
来获取无状态组件实例。
虽然无法通过ref获取无状态组件实例,但是可以结合复合组件来包装无状态组件来在其上使用ref引用。
另外,对于无状态组件我们想访问的无非是其中包含的组件或者dom元素,我们可以通过一个变量来保存我们想要的组件或者dom元素组件的实例引用。例如下面代码:
function TestComp(props){ let refDom; return (<p> </p><p> refDom = node}> ... </p> ) }
这样,可以通过变量refDom
来访问到无状态组件中的指定dom元素了,访问其中的其他组件实例类似。
ref在HOC中存在问题
react的HOC
是高阶组件,简单理解就是包装了一个低阶的组件,最后返回一个高阶的组件;高阶组件其实是在低阶组件基础上做了一些事情,比方说antd
组件的Form create
的方法,它就是在为低阶组件封装了一些特殊的属性,比如form
属性。
既然HOC
会基于低阶组件生成一个新的高阶组件,若用ref
就不能访问到我们真正需要的低阶组件实例,我们访问到的其实是高阶组件实例。所以:
若HOC不做特殊处理,ref是无法访问到低阶组件实例的
要想用ref
访问低阶组件实例,就必须得HOC支持,就像Redux
的connect方法提供的withRef
属性来访问低阶组件一样。具体可以参考这里。
总结
ref
提供了一种对于react标准的数据流不太适用的情况下组件间交互的方式,例如管理dom元素focus、text selection以及与第三方的dom库整合等等。 但是在大多数情况下应该使用react响应数据流那种方式,不要过度使用ref。
另外,在使用ref时,不用担心会导致内存泄露的问题,react会自动帮你管理好,在组件卸载时ref值也会被销毁。
最后补充一点:
不要在组件的
render
方法中访问ref
引用,render
方法只是返回一个虚拟dom,这时组件不一定挂载到dom中或者render返回的虚拟dom不一定会更新到dom中。