Render --- 四种不同的render方法

3,967 阅读2分钟

render顾名思义就是渲染的意思,纵观整个React有三个不同的地方,定义了各自的render方法。

虽然有多个不同的render方法,但是render方法的作用却是一致的,都是调用 createElement方法来生成一个Element。

① ReactDOM.render

这个render的是将子树挂载在根元素上。这个过程很长,会递归每一个挂载实例的mountComponent方法生成markup,最后将markup作为innerHTML属性的值放在根元素内。

经过Babel转译之后的 ReactDOM.render如下所示:

    _reactDom["default"].render(_react["default"].createElement(App, null), document.getElementById("app"));

如上所示,这个时候的render方法就是创建一个 App 的Element。

② TopLevelWrapper.prototype.render

根元素就是HTML文件的一个id为app的div。React会将组件都挂载在这个元素内

在ReactDOM.render方法在此执行的过程中根元素也会被创建为Element。叫做被包装的Element---也就是WrappedElement。

   WrappedElement =  new ReactElement(TopLevelWrapper, null, null, null, null, null, nextElement);

参数: TopLevelWrapper 如下:

    TopLevelWrapper.prototype.render = function () {
        return this.props;
    };

参数:nextElement 就是App组件的Element形式。

new ReactElement 的时候, TopLevelWrapper方法 为type。 nextElement 也就是App 组件的Element则为props

此时的render方法是挂载在 type的原型上的。

注意:WrappedElement 实例化之后也是一个组件,一个 ReactCompositeComponent 类型的组件。我们叫他 WrappedInstance

这里的render被用到的地方是在 ReactCompositeComponent 实例的mountComponent方法中。我们去获取一个组件要渲染的Element(其实就是一个组件的内容)--- renderedElement的时候,调用render来拿到这些要真正渲染的Element。

根元素要渲染的Element只有 App Element。所以其render方法返回的是this.porps. this指代的便是 WrappedElement。

③ 自定义组件的render

React规定自定义的组件必须要有一个render方法,而和这个方法必须要返回一个东西,可以是jsx语法的类html代码,或者是null或者是false。 这里的render 与②中的render是不一样的 ,这里的render有明确的返回内容,也ius明确的渲染内容,这些内容是开发者为其准备的。

render返回的内容。

组件的render方法会在组件的挂载实例的 mountComponent 方法中调用,返回的是一个 renderElement。也就是一种Element,这个renderElement有一个属性props,props也有一个属性 children,children是一个数组,数组里包含了组件的render方法所返回的全部内容,也就是我们定义组件的时候用jsx语法写成的类似HTMl的代码。这里React会将每一个类HTML标签都当做数组里的一项进行存储。

④ StatelessComponent 组件的render方法

如下所示:

    function StatelessComponent(Component) {}
    StatelessComponent.prototype.render = function () {
      var Component = ReactInstanceMap.get(this)._currentElement.type;
      return Component(this.props, this.context, this.updater);
    };

是对于无状态的箭头函数组件定义的render方法

一个无状态的箭头函数组件如下所示

    import React from "react";

    const Stateless = () => <div>Hello </div>;
    export default Stateless;
    

这个render方法并没有被使用。