本次分析的源碼採用的是16.4.1的版本數組
React.Children
提供了處理 this.props.children 的工具集:安全
咱們先來看看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
這裏發現setState 和 forceUpdate方法掛在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方法的蹤跡,源碼還沒讀完......