基于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方法的踪迹,源码还没读完......

相关文章
相关标签/搜索