//說明
/**
* ReactDOM.render(
* <h1>Hello, world!</h1>,
* document.getElementById('root')
* );
* babel轉譯之後
* ReactDOM.render(React.createElement("h1", null, "Hello, world!"),
* document.getElementById('root'));
* 所以首先需要一個函數createElement來轉寫html標籤語法(JSX)
* 然後需要一個render函數掛載到dom裏
*/
let React = (function(){
class Component{
static isReactComponent = true;//區分是函數還是類的標識(class通過babel轉譯後也是函數)
constructor(props){
this.props = props;
}
}
function ReactElement(type,props){
const element = {type,props}
return element;
}
function createElement(type,config,children){
let propsName;
const props = {};
for(propName in config){
props[propName] = config[propName];
}
const childrenLength = arguments.length - 2;
if(childrenLength ==1){
props.children = children;
}else if(childrenLength>1){
props.children = Array.from(arguments).slice(2);
}
return ReactElement(type,props);
}
return {
createElement,Component
}
})()
let ReactDom = (function(){
function render(element,parentNode){
if(typeof element == 'string' || typeof element == 'number'){
return parentNode.appendChild(document.createTextNode(element));
}
let {type,props} = element;
if(type.isReactComponent){
let returnElement =new type(props).render();
type = returnElement.type;
props = returnElement.props;
}else if(typeof type == 'function'){
let returnElement = type(props);
type = returnElement.type;
props = returnElement.props;
}
let domElement = document.createElement(type);
for(let propName in props){
if(propName == 'className'){
domElement.className = props[propName];
}else if(propName == 'style'){
let styleObj = props[propName];
for(let attr in styleObj){
domElement.style[attr] = styleObj[attr];
}
}else if(propName == 'children'){
let children = Array.isArray(props.children)?props.children:[props.children];
children.forEach(child=>render(child,domElement));
}else{
domElement.setAttribute(propName,props[propName])
}
}
parentNode.appendChild(domElement)
}
return {
render
}
})()
//普通使用
let element = React.createElement('h1',{
className:'title',
style:{
color:'red',
fontSize:'50px'
}
},"hello",React.createElement("span",null,"常規寫法"));
ReactDom.render(element,document.getElementById('root'));
//函數組件調用
function welcome1(props){
return React.createElement("h1",{id:'welcome'},props.name,props.age)
}
let element1 = React.createElement(welcome1,{name:'函數',age:'10'})
ReactDom.render(element1,document.getElementById('root'))
//類組件調用
class Welcome2 extends React.Component{
render(){
return React.createElement("h1",{id:'welcome'},this.props.name,this.props.age)
}
}
let element2 = React.createElement(Welcome2,{name:'類',age:'10'})
ReactDom.render(element2,document.getElementById('root'))