摘要:一作用獲取目標(biāo)的實(shí)例使用源碼可修改的不可變的對(duì)象沒(méi)見(jiàn)過(guò)這種寫法初始化對(duì)象,屬性初始值為解析源碼比較簡(jiǎn)單,就是返回了帶有屬性的二作用從父組件中獲取子組件是的實(shí)例使用是沒(méi)有實(shí)例的,因?yàn)樗牵詻](méi)有,所以不能通過(guò)來(lái)拿到實(shí)例將的傳給子組件,并綁定
一、React.createRef()
GitHub:
https://github.com/AttackXiaoJinJin/reactExplain/blob/master/react16.8.6/packages/react/src/ReactCreateRef.js
作用:
獲取目標(biāo)element的DOM實(shí)例
使用:
import React from "react" export default class Father extends React.Completed{ constructor(props){ super(props) this.father=React.createRef() } componentDidMount(){ this.father.current.value="hahhaha" } render(){ returnthis is div} }
源碼:
import type {RefObject} from "shared/ReactTypes"; // an immutable object with a single mutable value //可修改value的 不可變的對(duì)象 //沒(méi)見(jiàn)過(guò)這種寫法 :RefObject export function createRef(): RefObject { //初始化ref對(duì)象,屬性current初始值為null const refObject = { current: null, }; if (__DEV__) { Object.seal(refObject); } return refObject; }
解析:
源碼比較簡(jiǎn)單,就是返回了帶有current屬性的refObject
二、React.forwardRef()
GitHub:
https://github.com/AttackXiaoJinJin/reactExplain/blob/master/react16.8.6/packages/react/src/forwardRef.js
作用:
從父組件中獲取子組件是FunctionComponent的DOM實(shí)例
使用:
import React from "react" //funciton component是沒(méi)有dom實(shí)例的,因?yàn)樗荘ureComponent,所以沒(méi)有this, // 所以不能通過(guò)createRef()來(lái)拿到實(shí)例 //將Father的father傳給子組件,并綁定子組件的DOM實(shí)例,從而能在父組件拿到子組件的DOM實(shí)例 const Child=React.forwardRef((props,ref)=>{ returnchild div}) export default class Father extends React.Completed{ constructor(props){ super(props) this.father=React.createRef() } componentDidMount(){ this.father.current.value="hahhaha" } render(){ return} }
源碼:
import {REACT_FORWARD_REF_TYPE, REACT_MEMO_TYPE} from "shared/ReactSymbols"; import warningWithoutStack from "shared/warningWithoutStack"; export default function forwardRef( render: (props: Props, ref: React$Ref ) => React$Node, ) { //__DEV__可不看 if (__DEV__) { if (render != null && render.$$typeof === REACT_MEMO_TYPE) { warningWithoutStack( false, "forwardRef requires a render function but received a `memo` " + "component. Instead of forwardRef(memo(...)), use " + "memo(forwardRef(...)).", ); } else if (typeof render !== "function") { warningWithoutStack( false, "forwardRef requires a render function but was given %s.", render === null ? "null" : typeof render, ); } else { warningWithoutStack( // Do not warn for 0 arguments because it could be due to usage of the "arguments" object render.length === 0 || render.length === 2, "forwardRef render functions accept exactly two parameters: props and ref. %s", render.length === 1 ? "Did you forget to use the ref parameter?" : "Any additional parameter will be undefined.", ); } if (render != null) { warningWithoutStack( render.defaultProps == null && render.propTypes == null, "forwardRef render functions do not support propTypes or defaultProps. " + "Did you accidentally pass a React component?", ); } } return { //被forwardRef包裹后,組件內(nèi)部的$$typeof是REACT_FORWARD_REF_TYPE $$typeof: REACT_FORWARD_REF_TYPE, //render即包裝的FunctionComponent,ClassComponent是不用forwardRef的 render, }; }
解析:
(1)不看__DEV__的話,返回的也是一個(gè)Object,也就是說(shuō),Child被forwardRef包裹后,React.forwardRef(Child)的$$typeof是REACT_FORWARD_REF_TYPE
注意:
一旦在Father組件中,用JSX引用了Child組件,那么就是React.createElement(React.forwardRef(Child)),又包裹了一層,此時(shí)的$$typeof`是`REACT_ELEMENT_TYPE`,`type`是`React.forwardRef(Child)`,`type`里面的`$$typeof是REACT_FORWARD_REF_TYPE
const ReactElement = function(type,...) { const element = { $$typeof: REACT_ELEMENT_TYPE, type: type, }; }
(2)關(guān)于forward在高階組件的用法,請(qǐng)參考:https://reactjs.org/docs/react-api.html#reactforwardref
(3)如何在antdPro/FunctionComponent中使用:
子:
const Child = (props,ref) => { const inputRef = React.useRef(); React.useImperativeHandle(ref, () => ({ focus: () => { // inputRef.current.focus(); inputRef.current.value="aaaa" } })); return () } export default React.forwardRef(Child)
父:
import Child from "./Child"; const Father=(props)=> { const rref= React.useRef(null) useEffect(() => { //console.log(rref.current,"rref33") rref.current.focus() }, []); return () }
注意:
① antdPro中使用的話,我試了是不好用dva的connect包裹的,issue上作者也沒(méi)回答,就關(guān)閉了:https://github.com/ant-design/ant-design-pro/issues/3123
② useImperativeMethods已經(jīng)重命名為useImperativeHandle,傳送門:https://github.com/facebook/react/pull/14565
(完)
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/106050.html
摘要:本次分析的源碼采用的是的版本核心接口提供了處理的工具集我們先來(lái)看看做了什么事情即當(dāng)為空時(shí),返回不為時(shí)調(diào)用,最終返回一個(gè)數(shù)組這里說(shuō)一下,可以通過(guò)傳入的對(duì)所有子組件進(jìn)行操作,具體使用方法看下圖參數(shù)通過(guò)配合的例子把父組件的賦值給每個(gè)子組件我們先不 本次分析的源碼采用的是16.4.1的版本 核心接口 showImg(https://segmentfault.com/img/bVbeT9f?w=...
摘要:在前端開發(fā)過(guò)程中,源碼解讀是必不可少的一個(gè)環(huán)節(jié),我們直接進(jìn)入主題,注意當(dāng)前版本號(hào)。注意包文件僅僅是的必要的功能性的定義,它必須要結(jié)合一起使用下是,原生環(huán)境下是。 在前端開發(fā)過(guò)程中,源碼解讀是必不可少的一個(gè)環(huán)節(jié),我們直接進(jìn)入主題,注意當(dāng)前 React 版本號(hào) 16.8.6。 注意:react 包文件僅僅是 React components 的必要的、功能性的定義,它必須要結(jié)合 React...
摘要:通常在組件的構(gòu)造函數(shù)內(nèi)創(chuàng)建,使其在整個(gè)組件中可用。例如純文本查看復(fù)制代碼如上所示一個(gè)實(shí)例在構(gòu)造函數(shù)中創(chuàng)建,并賦值給在方法內(nèi)部,將構(gòu)造函數(shù)中創(chuàng)建的傳遞給接下來(lái),讓我們看一個(gè)在組件中使用的示例。回調(diào)回調(diào)是在中使用的另一種方式。 使用 React 時(shí),我們的默認(rèn)思維方式應(yīng)該是 不會(huì)強(qiáng)制修改 DOM ,而是通過(guò)傳入 props 重新渲染組件。但是,有些情況卻無(wú)法避免修改 DOM 。React ...
摘要:引言于發(fā)布版本,時(shí)至今日已更新到,且引入了大量的令人振奮的新特性,本文章將帶領(lǐng)大家根據(jù)更新的時(shí)間脈絡(luò)了解的新特性。其作用是根據(jù)傳遞的來(lái)更新。新增等指針事件。 1 引言 于 2017.09.26 Facebook 發(fā)布 React v16.0 版本,時(shí)至今日已更新到 React v16.6,且引入了大量的令人振奮的新特性,本文章將帶領(lǐng)大家根據(jù) React 更新的時(shí)間脈絡(luò)了解 React1...
摘要:為管理提供了一個(gè)新的方案,它為字符串提供了方便,并且沒(méi)有任何缺點(diǎn)司徒正美注意除了新的外,回調(diào)將繼續(xù)得到支持。例如司徒正美通常會(huì)將傳遞給它們包裝的組件。 幾天前,我們寫了一篇關(guān)于即將到來(lái)的對(duì)我們的傳統(tǒng)生命周期方法的變更的文章,包括逐步遷移策略。在React 16.3.0中,我們添加了一些新的生命周期方法來(lái)幫助遷移。我們還引入了新的API,用于長(zhǎng)時(shí)間請(qǐng)求的特性:一個(gè)官方的上下文API、一個(gè)...
閱讀 2826·2021-11-24 09:39
閱讀 3397·2021-11-19 09:40
閱讀 2265·2021-11-17 09:33
閱讀 3756·2021-10-08 10:04
閱讀 3047·2021-09-26 09:55
閱讀 1672·2021-09-22 15:26
閱讀 934·2021-09-10 10:51
閱讀 3135·2019-08-30 15:44