这是我参与更文挑战的第 26 天,活动详情查看: 更文挑战
组件
组件可能是函数还可能是类,我们知道只要继承 Component 类就是 react 的组件。
function Box(){
return (
<div className='box' size="24">
hello,<span>zidea</span>
</div>
)
}
复制代码
创建一个函数,函数名为 Box 函数返回一个 jsx 对象
ReactDOM.render(<Box name={title}/>,document.querySelector("#root"));
复制代码
传入一个名称为 title 的对象,
整理代码
function _render(vnode){
//TODO
if(vnode === undefined ) return;
// vnode is equal string
if(typeof vnode === 'string'){
//create textNode
return document.createTextNode(vnode)
}
// deconstruct vnode
const {tag,attrs} = vnode;
//create dom object
const dom = document.createElement(tag)
if(attrs){
// property key: className box
Object.keys(attrs).forEach(key=>{
const val = attrs[key]
setAttribute(dom,key,val)
})
}
vnode.children.forEach(child=>render(child,dom))
return dom;
}
复制代码
在 javascript 中,如果函数名称以下划线开头通常是私有方法。这里把渲染设置为私有方法,也就是渲染逻辑放置在 _render
方法中。然后 _render
方法主要就是讲虚拟节点处理 dom 节点返回出来。
return dom;
返回 dom 而不是将 dom 添加到容器节点中return document.createTextNode(vnode)
通常
function render(vnode,container){
container.appendChild(_render(vnode))
}
复制代码
渲染方法(_render)
if(vnode === undefined || vnode === null || typeof vnode === 'boolean') vnode = '';
复制代码
判断 tag 是函数,tag 可能是函数组件或类组件
if(typeof vnode.tag === 'function')
通过虚拟节点 tag 值来判断是否为组件,然后按组件进行处理
- 创建组件
const comp = createComponent(vnode.tag,vnode.attrs);
2. 设置组件的属性
setComponentProps(comp,vnode.attrs);
3. 组件渲染的节点返回对象
return comp.base;
这里我们不能返回组件,而需要将节点对象挂接到 comp 的 base 属性上,然后返回comp.base
的个节点对象。
创建组件
function createComponent(comp,props){
//declare component instance
let instance;
// class component case
if(comp.prototype && comp.prototype.render){
instance = new comp(propos)
}else{ // function component case
//conver function component to class component
instance = new Component(props)
//constructor prefer to function(component)
instance.constructor = comp;
//define render function
instance.render = function(){
//return jsx object
return this.constructor(props)
}
}
return instance;
}
复制代码
- 对于类组件,相对函数组件要好处理,只需要实例化(new)该类,然后将 props 做出参数传入即可。
- 如果组件是函数组件,我们需要将函数组件转为类组件,这样做的好处是便于以后管理组件。这里我们在
react
文件夹下创建一个component.js
类其中定义 Component 类
class Component{
constructor(props = {}){
this.props = props;
this.state = {};
}
}
export default Component;
复制代码
- 在构造函数接收 props 参数,这是从外部传入的参数,然后内部维护一个状态对象 state
复制代码
- 接下来问题是如何获取 jsx 对象,其实在函数组价,jsx 对象作为返回值,我们构造函数依然已经指向了该函数,只要 render 函数返回该函数的返回值即可。
instance.render = function(){
//return jsx object
return this.constructor(props)
}
复制代码
设置组件属性
function setComponentProps(comp,props){
//设置组件的属性
comp.propos = props;
renderComponent(comp)
}
复制代码
渲染组件
function renderComponent(comp){
let base;
//call render method to return jsx object
const renderer = comp.render();
//conver jsx to dom obj
base = _render(renderer);
console.log(base)
comp.base = base
}
复制代码
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END