render方法指的是该组件将要如何渲染,一定并且只返回一个React元素。


image.png

jsx到JS对象结构

  1. return (
  2. <div>
  3. <h1 className='title'>hello</h1>
  4. </div>
  5. )
  6. Babel 转译 + react.js 构造
  7. return (
  8. React.createElement(
  9. "div",
  10. null,
  11. React.createElement(
  12. "h1",
  13. { className: 'title' },
  14. "React 小书"
  15. )
  16. )
  17. )

JS 对象结构到真实的dom元素

  1. // 过程版
  2. let eleObj = {
  3. type: 'div', // type 元素类型是div
  4. props: {
  5. id: 1,
  6. className: 'red',
  7. children: ['hello']
  8. }
  9. };
  10. // 写一个render方法(把eleObj插入到容器container中去)
  11. function render(eleObj, container) {
  12. let { type, props } = eleObj; // 解构赋值一下
  13. let ele = document.createElement(type); // 第一步创建一个dom元素,第二步再把所有属性赋给ele
  14. for(let attr in props) {
  15. if(attr == 'children') {
  16. props[attr].forEach(function(item) {
  17. let textNode = document.createTextNode(item);
  18. ele.appendChild(textNode);
  19. })
  20. }else if(attr == 'className') {
  21. ele.setAttribute('class', props[attr]);
  22. }else{
  23. ele.setAttribute(attr, props[attr]);
  24. }
  25. }
  26. container.appendChild(ele);
  27. }
  1. // 完整版
  2. let eleObj = {
  3. type: 'div', // type 元素类型是div
  4. props: {
  5. id: 1,
  6. className: 'red',
  7. children: ['hello', {
  8. type: 'span',
  9. props: {className: 'blue', children: ['word']}
  10. }]
  11. }
  12. };
  13. function render(eleObj, container) {
  14. let { type, props } = eleObj; // 解构赋值一下,解构出标签的 类型和属性对象
  15. let ele = document.createElement(type); // 第一步创建一个dom元素,第二步再把所有属性赋给ele
  16. // 循环props对象
  17. for(let attr in props) {
  18. if(attr == 'children') {
  19. props[attr].forEach(function(item) {
  20. if(typeof item == 'string') {
  21. let textNode = document.createTextNode(item);
  22. ele.appendChild(textNode);
  23. }else{
  24. render(item, ele) // 递归
  25. }
  26. })
  27. }else if(attr == 'className') {
  28. ele.setAttribute('class', props[attr]);
  29. }else{
  30. ele.setAttribute(attr, props[attr]);
  31. }
  32. }
  33. container.appendChild(ele);
  34. }
  1. import ReactDOM from 'react-dom';
  2. // react-dom 负责把这个用来描述 UI 信息的 JavaScript 对象变成 DOM 元素,并且渲染到页面上。

屏幕快照 2019-06-21 下午4.03.56.png

react源码 render方法

render方法可以传入三个参数包括ReactElement、DOM的包裹节点,和渲染结束后执行的回调方法。

  1. render(
  2. element: React$Element<any>,
  3. container: DOMContainer,
  4. callback: ?Function,
  5. ) {
  6. invariant(
  7. isValidContainer(container),
  8. 'Target container is not a DOM element.',
  9. );
  10. return legacyRenderSubtreeIntoContainer(
  11. null,
  12. element,
  13. container,
  14. false,
  15. callback,
  16. );
  17. },

react 工程代码:

  1. ReactDOM.render(
  2. <React.Fragment>
  3. <NormalComponent />
  4. {/* <AA /> */}
  5. <Main />
  6. </React.Fragment>,
  7. document.getElementById('root')
  8. );