instantiateComponent.js 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. import {
  2. getChildContext,
  3. getContextByTypes
  4. } from './context';
  5. import {
  6. mergeState
  7. } from '../util';
  8. var mountOrder = 0;
  9. export function buildComponentFromVnode(vnode) {
  10. var props = vnode.props;
  11. var key = vnode.key;
  12. var ref = vnode.ref;
  13. var context = vnode.context;
  14. var inst, rendered;
  15. var Ctor = vnode.type;
  16. //Component PureComponent
  17. if (Ctor.prototype && Ctor.prototype.render) {
  18. //props, context需要放在前俩
  19. inst = new Ctor(props, context, key, ref);
  20. //constructor里面props不可变
  21. inst.props = props;
  22. inst.refType = vnode.refType;
  23. inst.mayInst.mountOrder = mountOrder;
  24. mountOrder++;
  25. //_lifeState来控制生命周期中调用setState的作用
  26. //为0代表刚创建完component实例 (diff之后也会重置为0)
  27. inst.mayInst.lifeState = 0;
  28. if (inst.componentWillMount) {
  29. //此时如果在componentWillMount调用setState合并state即可
  30. //为1代表componentWillMount
  31. inst.mayInst.lifeState = 1;
  32. inst.componentWillMount();
  33. }
  34. if (inst.mayInst.mergeStateQueue) {
  35. inst.state = mergeState(inst);
  36. }
  37. //为2代表开始render
  38. //children 初次render的生命周期render DidMount
  39. //调用父组件的setState 都放在父组件的下一周期;
  40. inst.mayInst.lifeState = 2;
  41. rendered = inst.render(props, context);
  42. if (inst.getChildContext) {
  43. context = getChildContext(inst, context);
  44. }
  45. if (vnode.getContext) {
  46. inst.context = getContextByTypes(context, Ctor.contextTypes);
  47. }
  48. rendered && (rendered.mayInfo.refOwner = inst);
  49. } else {
  50. //StatelessComponent 我们赋给它一个inst 省去之后判断inst是否为空等;
  51. inst = {
  52. mayInst: {
  53. stateless: true
  54. },
  55. render: function (type) {
  56. return type(this.props, this.context);
  57. }
  58. }
  59. rendered = inst.render.call(vnode, Ctor);
  60. //should support module pattern components
  61. if (rendered && rendered.render) {
  62. console.warn('不推荐使用这种module-pattern component建议换成正常的Component形式,目前只支持render暂不支持其它生命周期方法')
  63. rendered = rendered.render.call(vnode, props, context);
  64. }
  65. }
  66. if (rendered) {
  67. //需要向下传递context
  68. rendered.context = context;
  69. }
  70. vnode.mayInfo.instance = inst;
  71. inst.mayInst.rendered = rendered;
  72. return rendered;
  73. }