React 源碼閱讀-5_036

React 源碼閱讀-5

源碼


import {REACT_FORWARD_REF_TYPE, REACT_MEMO_TYPE} from 'shared/ReactSymbols';

import warningWithoutStack from 'shared/warningWithoutStack';

export default function forwardRef<Props, ElementType: React$ElementType>(
  render: (props: Props, ref: React$Ref<ElementType>) => React$Node,
) {

// ... 暫時忽略 也看不太懂
//應該這部分代碼是爲了在DevTools中顯示一個自定義名稱 不太確定

  return {
    $$typeof: REACT_FORWARD_REF_TYPE,
    render,
  };
}

React.forwardRef 接受一個渲染函數,該函數接收 propsref 參數並返回一個 React 節點

爲了在高階組件中轉發 refs

forwardRef例子

const FancyButton = React.forwardRef((props, ref) => (
  <button ref={ref} className="FancyButton">
    {props.children}
  </button>
));

// 你可以直接獲取 DOM button 的 ref:
const ref = React.createRef();
<FancyButton ref={ref}>Click me!</FancyButton>;

1.我們通過調用 React.createRef 創建了一個 React ref 並將其賦值給 ref 變量。

2.我們通過指定 refJSX 屬性,將其向下傳遞給<FancyButton ref={ref}>

3.React 傳遞 reffowardRef 內函數 (props, ref) => ...,作爲其第二個參數。

4.我們向下轉發該 ref 參數到<button ref={ref}>,將其指定爲 JSX 屬性。

5.當 ref掛載完成,ref.current 將指向 <button> DOM節點。

用法

  • 寫高階組件時,返回的無狀態組件用 forwardRef 包裹,並且可以傳遞第二個參數 ref
  • 無狀態組件中的返回值可將 ref 作爲 props 傳入。
import React from 'react'

// 高階組件,注意返回值用 `React.forwardRef` 包裹
// 裏面的無狀態組件接收第二個參數:ref
const paintRed = Component => React.forwardRef(
    // 此例中,ref 爲 ForwardRef 中的 textRef
    (props, ref) => (
        <Component color='red' ref={ref} {...props}></Component>
    )
)

class Text extends React.Component {
    // 僅用於檢測是否取到 ref
    value = 1
    render() {
        const style = {
            color: this.props.color
        }
        return (
            <p style={style}>
                我是紅色的!
            </p>
        )
    }
}

const RedText = paintRed(Text)

export default class ForwardRef extends React.Component {
    textRef = React.createRef()
    componentDidMount() {
        // value = 1
        console.log(this.textRef.current.value)
    }
    render() {
        // 如果沒有 forwardRef,那麼這個ref只能得到 `RedText`,而不是裏面的 `Text`
        return (
            <RedText ref={this.textRef}></RedText>
        )
    }
}

大部分需要使用 forwardRef 的時候都可以用其他方式解決.

https://juejin.im/post/5ad949...
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章