国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

React源碼解析之React.createRef()/forwardRef()

aisuhua / 3718人閱讀

摘要:一作用獲取目標的實例使用源碼可修改的不可變的對象沒見過這種寫法初始化對象,屬性初始值為解析源碼比較簡單,就是返回了帶有屬性的二作用從父組件中獲取子組件是的實例使用是沒有實例的,因為它是,所以沒有,所以不能通過來拿到實例將的傳給子組件,并綁定

一、React.createRef()
GitHub:
https://github.com/AttackXiaoJinJin/reactExplain/blob/master/react16.8.6/packages/react/src/ReactCreateRef.js

作用:
獲取目標elementDOM實例

使用:

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(){
    return 
this is div
} }

源碼:

import type {RefObject} from "shared/ReactTypes";

// an immutable object with a single mutable value
//可修改value的 不可變的對象
//沒見過這種寫法 :RefObject
export function createRef(): RefObject {
  //初始化ref對象,屬性current初始值為null
  const refObject = {
    current: null,
  };
  if (__DEV__) {
    Object.seal(refObject);
  }
  return refObject;
}

解析:
源碼比較簡單,就是返回了帶有current屬性的refObject

二、React.forwardRef()
GitHub:
https://github.com/AttackXiaoJinJin/reactExplain/blob/master/react16.8.6/packages/react/src/forwardRef.js

作用:
從父組件中獲取子組件是FunctionComponentDOM實例

使用:

import React from "react"
//funciton component是沒有dom實例的,因為它是PureComponent,所以沒有this,
// 所以不能通過createRef()來拿到實例

//將Father的father傳給子組件,并綁定子組件的DOM實例,從而能在父組件拿到子組件的DOM實例
const Child=React.forwardRef((props,ref)=>{
  return 
child 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包裹后,組件內部的$$typeof是REACT_FORWARD_REF_TYPE
    $$typeof: REACT_FORWARD_REF_TYPE,
    //render即包裝的FunctionComponent,ClassComponent是不用forwardRef的
    render,
  };
}

解析:
(1)不看__DEV__的話,返回的也是一個Object,也就是說,ChildforwardRef包裹后,React.forwardRef(Child)$$typeofREACT_FORWARD_REF_TYPE

注意:
一旦在Father組件中,用JSX引用了Child組件,那么就是React.createElement(React.forwardRef(Child)),又包裹了一層,此時的$$typeof`是`REACT_ELEMENT_TYPE`,`type`是`React.forwardRef(Child)`,`type`里面的`$$typeofREACT_FORWARD_REF_TYPE

const ReactElement = function(type,...) {
  const element = {
    $$typeof: REACT_ELEMENT_TYPE,
    type: type,
  };
}

(2)關于forward在高階組件的用法,請參考: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中使用的話,我試了是不好用dvaconnect包裹的,issue上作者也沒回答,就關閉了:https://github.com/ant-design/ant-design-pro/issues/3123

useImperativeMethods已經重命名為useImperativeHandle,傳送門:https://github.com/facebook/react/pull/14565

(完)

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/106050.html

相關文章

  • 基于React版本16.4的源碼解析(一)

    摘要:本次分析的源碼采用的是的版本核心接口提供了處理的工具集我們先來看看做了什么事情即當為空時,返回不為時調用,最終返回一個數組這里說一下,可以通過傳入的對所有子組件進行操作,具體使用方法看下圖參數通過配合的例子把父組件的賦值給每個子組件我們先不 本次分析的源碼采用的是16.4.1的版本 核心接口 showImg(https://segmentfault.com/img/bVbeT9f?w=...

    joywek 評論0 收藏0
  • React 源碼漂流(一) 起航

    摘要:在前端開發過程中,源碼解讀是必不可少的一個環節,我們直接進入主題,注意當前版本號。注意包文件僅僅是的必要的功能性的定義,它必須要結合一起使用下是,原生環境下是。 在前端開發過程中,源碼解讀是必不可少的一個環節,我們直接進入主題,注意當前 React 版本號 16.8.6。 注意:react 包文件僅僅是 React components 的必要的、功能性的定義,它必須要結合 React...

    Mr_zhang 評論0 收藏0
  • 如何在 React 組件中正確使用 Refs的指南

    摘要:通常在組件的構造函數內創建,使其在整個組件中可用。例如純文本查看復制代碼如上所示一個實例在構造函數中創建,并賦值給在方法內部,將構造函數中創建的傳遞給接下來,讓我們看一個在組件中使用的示例。回調回調是在中使用的另一種方式。 使用 React 時,我們的默認思維方式應該是 不會強制修改 DOM ,而是通過傳入 props 重新渲染組件。但是,有些情況卻無法避免修改 DOM 。React ...

    Backache 評論0 收藏0
  • 精讀《React16 新特性》

    摘要:引言于發布版本,時至今日已更新到,且引入了大量的令人振奮的新特性,本文章將帶領大家根據更新的時間脈絡了解的新特性。其作用是根據傳遞的來更新。新增等指針事件。 1 引言 于 2017.09.26 Facebook 發布 React v16.0 版本,時至今日已更新到 React v16.6,且引入了大量的令人振奮的新特性,本文章將帶領大家根據 React 更新的時間脈絡了解 React1...

    Nosee 評論0 收藏0
  • React v16.3.0: New lifecycles and context API

    摘要:為管理提供了一個新的方案,它為字符串提供了方便,并且沒有任何缺點司徒正美注意除了新的外,回調將繼續得到支持。例如司徒正美通常會將傳遞給它們包裝的組件。 幾天前,我們寫了一篇關于即將到來的對我們的傳統生命周期方法的變更的文章,包括逐步遷移策略。在React 16.3.0中,我們添加了一些新的生命周期方法來幫助遷移。我們還引入了新的API,用于長時間請求的特性:一個官方的上下文API、一個...

    zombieda 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<