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

本次分析的源碼採用的是16.4.1的版本數組

核心接口

圖片描述


React.Children

提供了處理 this.props.children 的工具集:安全

  • map
  • forEach
  • count
  • toArray
  • only

咱們先來看看mapChildren作了什麼事情app


map: mapChildren

圖片描述

即當children爲空時,返回null;
不爲null時調用mapIntoWithKeyPrefixInternal,最終返回一個result數組.
這裏說一下,能夠經過傳入的func對全部子組件進行操做,具體使用方法看下圖參數
圖片描述函數

經過配合cloneElement的例子:工具

class RadioGroup extends Component {
    constructor(props){
        super(props);
    }
    renderChildren(props) {
        return React.Children.map(props.children, (child, index) => {
            if (child.type === RadioOption)
                return React.cloneElement(child, {
                    // 把父組件的props.name賦值給每一個子組件
                    name: props.name
                })
            return child
        })
    }
    render() {
        return (
            <div>
                {this.renderChildren(this.props)}
            </div>
        )
    }
}

forEach、count、toArray咱們先不看,先看下onlythis


only: onlyChild

圖片描述

看註釋就能明白了
這個函數會返回第一個children,同時經過isValidElement判斷是否是惟一的一個,若不是會報錯spa

由於若只有一個那必定是一個Object對象,不然爲一個數組
因此能夠經過判斷是否爲children是否是一個Object對象
咱們來看下函數驗證一下
圖片描述線程

果真有個一判斷是否爲Object的條件,剩下兩個是判斷是否爲null和$$typeof是否爲elementrest


React.createRef

照舊看下源碼
圖片描述code

這裏發現用了Object.seal方法來封閉了refObject,即阻止添加新屬性並將全部現有屬性標記爲不可配置。當前屬性的值只要可寫就能夠改變,這裏說下不可變(immutable)對象的幾個好處:

  • 線程安全
  • 易於理解
  • 比可變對象有更高的安全性

createRef是React 16.3 發佈的方法
同時還有一個用於高階組件的forwardRef
基本原理是經過劫持ref而且將之轉換成prop實現的
具體使用以下

function HOC(WrappedComponent) {
    class HOC extends React.Component {
        constructor(props){
            super(props);
        }
      render() {
        const {forwardedRef, ...rest} = this.props;
        return <WrappedComponent ref = {forwardedRef} {...rest} />;
      }
    }
    return React.forwardRef((props, ref) => {
        return <HOC {...props} forwardedRef = {ref} />;
    });;
}
class Child extends React.Component{
    constructor(props){
      super(props);
    }
    render(){
      return <input />
    }
}
const LogProps = HOC(Child);

class Father extends React.Component{
    constructor(props){
      super(props);
      this.myRef = React.createRef();
    }
    componentDidMount(){
      console.log(this.myRef.current);
    }
    render(){
      return <LogProps ref = {this.myRef}/>
    }
}

React.Component 和 React.PureComponent

這裏是Component
圖片描述

這裏是PureComponent
圖片描述

這裏是ComponentDummy
圖片描述

這裏發現setStateforceUpdate方法掛在Component下,經過一個ComponentDummy的「僞組件」來看成中介,使PureComponent也能訪問到setState 和 forceUpdate方法。
細心的可能發現這裏有個objectAssign方法,這個方法把Component的原型跟PureComponent的原型合併了,也就是說PureComponent和Component共用了一個原型
圖片描述

這裏的shouldUseNative()是對原生的assgin方法進行兼容性判斷,我把源碼貼出來,有興趣的能夠看看
圖片描述


createFactory: createFactoryWithValidation

圖片描述

createElement: createElementWithValidation

圖片描述

在最後咱們能夠看到有一個判斷type === REACT_FRAGMENT_TYPE,這個REACT_FRAGMENT_TYPE是一個能夠包裹碎片化元素的組件
React.Fragment包裹碎片化的組件,能夠寫做

<>
    ...
  </>
  但可能有的編譯器不支持,最好寫做
  <React.Fragment>
    ...
  </React.Fragment>

看到如今都沒發現render方法的蹤跡,源碼還沒讀完......

相關文章
相關標籤/搜索