本次分析的源码采用的是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方法的踪迹,源码还没读完......