function render(element,container){
console.log(element)
if(typeof element === 'string' || typeof element === 'number'){
return container.appendChild(document.createTextNode(element))
}
let props,type
type = element.type
props = element.props
let isReactComponent = type.isReactComponent
console.log(type,"#####")
if(isReactComponent){
let componentInstance = new type(props)
element = componentInstance.render()
}else if(typeof type === 'function'){
element = type(props)
}
type = element.type
props = element.props
console.log(type,"*******")
let dom = createDOM(type,props)
console.log(dom)
container.appendChild(dom)
}
function createDOM(type,props){
let dom = document.createElement(type)
for(let propName in props){
if(propName === 'children'){
if(!Array.isArray(props.children)){
render(props.children,dom)
}else{
props.children.forEach((child)=>render(child,dom))
}
}else{
if(typeof props[propName] === 'object'){
for(let key in props[propName]){
dom.style[key] = props[propName][key]
}
}else{
dom.setAttribute(propName,props[propName])
}
}
}
return dom
}
export default {
render
}
此文件为react-dom.js
class Component{
static isReactComponent = true
constructor(props){
this.props = props
}
}
function createElement(type,config = {},...children){
let child = children
if(child.length === 1){
child = child[0]
}
let props = {...config,children:child}
return {
type,
props
}
}
export default {
createElement,
Component
}
此文件为react.js
import myReact from './handle/react';
import myReactDOM from './handle/react-dom'
// function Welcome(props){
// return myReact.createElement('h1',{
// className:'title',
// style:{
// color:'red'
// }
// },"hello"," ",myReact.createElement('span',null,"world"))
// }
class Welcome extends myReact.Component{
render(){
return myReact.createElement('h1',{
className:'title',
style:{
color:'red'
}
},"hello"," ",myReact.createElement('span',null,"world"))
}
}
let element = myReact.createElement(Welcome,{})
myReactDOM.render(element,document.getElementById('root'))
入口文件index.js
注意:
1.主要考虑ReactDOM结构和render方法里面的递归,以及目前children并不一定是数组的变化,就能很简单的写出来一个demo
2.区分函数组件还是class组件通过type.isReactComponent 静态属性来判断
3.react.js里面的createElement配合2021年1.19日的结构,children并不一定是数组,来组成数据结构
4.感想:写源码和写业务一样。