foveluy / luy Goto Github PK
View Code? Open in Web Editor NEWa React-like framework
License: Other
a React-like framework
License: Other
清除组件的时候,必须清除掉ref引用,防止内存泄漏
你好,最近在知乎上看到大神的这个项目,今天试了下学习案例/study
,发现其中的createElement.js
文件,虽然在study.js
中引用了,但是却没用使用,不懂为什么?另外如果没用使用createElement.js
,那vnode的生成是怎么做的呢,使用babel转的吗?
麻烦大神给解答一下。
读读你的代码学习一下!
本文主要讲解、理清、复习 Luy 之前的架构,以方便在重构后和重构前的对比,内容较多,算是对自己的一个复习。
createElement
:一切的开始在几年前,React 其实用的并不是 document.createElement
这个 API 去创建DOM节点,而是使用的 innerHTML 来创造 DOM 节点。换做这个的原因是因为 document.createElement
的速度远大于 innerHTML 这个东西。这一步的修改,给 React 带来了更大的性能提升。
在官方博客中,我们可以看到了官方给出的答案。
Using document.createElement is also faster in modern browsers and fixes a number of edge cases >related to SVG elements and running multiple copies of React on the same page.
如果不是公共库作者,我想业务程序员已经很少很少使用这个 API 去做事情了,取而代之的,大家使用的是 JSX
来代替这个函数。 React 给我启示就是自造了一种叫做 JSX 的语法糖,来代替 createElement
的调用,这里我就随便多嘴一句,不展开了。
将 JSX
转换成 React.createElement 的 Babel 插件叫做:
"transform-react-jsx",
{
"pragma": "React.createElement"
}
其中 pragma
的设置,就是我们将JSX
转化成的函数,React.createElement
是它的默认值。如果你改成:
"transform-react-jsx",
{
"pragma": "dom"
}
那么对应的JSX
就会变成:
<div>1</div>
|
|
v
dom('div',{},1)
createElement(type, config, ...children)
,这个函数的主要作用是构造一个 Vnode,所有的 DOM 节点,都会被对应到每一个 Vnode 中去,无论你是 虚拟DOM 节点、还是虚拟组件、还是虚拟无状态组件,都会被 Luy 统一起来变成一个 Vnode。这个函数运行完毕以后,返回的 Vnode 节点,我们来看看:
function Vnode(type, props, key, ref) {
this.owner = currentOwner.cur //这个是为了实现 ref的正确绑定
this.type = type // 节点的 type
this.props = props // 属性
this.key = key //用于diff的key
this.ref = ref // ref
}
然而,这个 Vnode 在 React 16 以后已经被改成了 fiber 结构,很多属性都已经不同,但是意义还是一样的:它是一个虚拟 DOM 节点。
构建虚拟 DOM 实际上是通过 Luy/vdom.js
代码下的render
函数进行的。这个函数就是我们经常使用的reactDOM.render
。这个函数一直有一个秘密,那就是它对已经绑定的节点,只会进行更新,而不是进行重新加载,这么做的原因是
代码其实很简单,就是做一个判断。对于同一个 dom 节点,运行两次 render,第一次是mount,第二次是更新。
if (typeNumber(container) !== 8) {
throw new Error('Target container is not a DOM element.')
}
const UniqueKey = container.UniqueKey
if (container.UniqueKey) {//已经被渲染
const oldVnode = containerMap[UniqueKey]
const rootVnode = update(oldVnode, Vnode, container)
runException();
return Vnode._instance
} else {
//第一次渲染的时候
Vnode.isTop = true;
container.UniqueKey = mountIndexAdd();
containerMap[container.UniqueKey] = Vnode;
renderByLuy(Vnode, container, false, Vnode.context, Vnode.owner);
runException();
return Vnode._instance;
}
开始构建虚拟dom的过程实际上是树的遍历,最简单的做法就是递归进行,在 Luy 中是这样的一个节奏:
renderByLuy()
|
|
| 原生节点
| document.createElement()
| /
v / 虚拟组件 (有状态组件、无状态组件)
根据节点信息 --> mountComponent() ----> mountChild()渲染子节点 ---->根据子节点继续遍历
\
\ 文字节点
mountTextComponent()
实际上,只要遇到树结构,都是这么个遍历的方法,递归一下就能够解决问题。
描述:
hascode={}会导致if (hascode === undefined) hascode = mapKeyToIndex(oldChild) 无法执行生成key映射。
解决:
#7
Luy介绍文字中正确应该为: 我的目标是,缔造一个和 React 一模一样的框架。
错误地方见下方:
所谓类React框架就是和 React 用法一模一样的框架。我的目标是,缔造一个和 React 一摸一样的框架。
class App extends Component {
state = {
info: true,
num:0
}
constructor(props) {
super(props)
setTimeout(() => {
this.setState({
info: !this.state.info
})
}, 1000)
}
updateNum(){
this.setState({
num:Math.random(1000)
})
}
render() {
const { num } = this.state
return (
<div>
<span>hello</span>
<div>1222{num}</div>
<div>
<button onClick={this.updateNum.bind(this)}>点击修改Num</button>
</div>
</div>
)
}
}
render(<App />, document.getElementById('root'))
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.