-
fiber, 这个数据结构记录了所要做的(更新节点, update, deletion, creation) 等所有信息. 本身是一个树形的结构, 父节点只连接子节点位于数组的第一个, 但是所有子节点都有父节点的引用
let fiber = { tag: HOST_COMPONENT, type: "div", // fiber 类型 parent: parentFiber, // parent fiber child: childFiber, // child fiber sibling: null, // slibing fiber alternate: currentFiber, // 指向当前未完成工作的 fiber, 以前的同一个位置节点的 fiber, 是为了记录 onUpdate(preProps, nextProps) 的 preProps 用的 stateNode: document.createElement("div"), // either dom instance, or a (React)class component instance props: { children: [], className: "foo"}, // props, 当前工作(mutation) 需要更新的props partialState: null, // next state effectTag: PLACEMENT, // delete, add or update effects: [] // other info related to effectTag, 子节点和孙子节点都会被pull 上来, 这里边只有root节点会真正用来操作dom, type of `fiber[]` };
-
理解 biber 的数据结构是非常重要的, fiber 有 child, parent, 各自指向 子节点 父节点, 而 sibling 可以理解为 链表的下一个节点, 需要注意的是 child 和 parent 是双向的, 而 sibling 是单向的.
-
wipFiber 和 rootFiber or _rootContainerFiber, fiber 的工作机制是 fiber 中记录了上次所有节点的关联信息, 然后在 effects 中记录了需要做的操作. 当 wipFiber 中的 mutation 被操作完, wipFiber 就会变成 rootFiber or _rootContainerFiber, 然后下一次渲染的时候会生成一个新的 wipFiber, 然后 这个 wipFiber.alternate 会被置为上次的 wipFiber 即 (rootFiber), 然后会将新的 elements 节点和老的 fiber 做个对比. 从根节点开始向下对比 , 产生 creation, deletion or update 的 effectType. fiber 中也缓存了上次的 instance (React.Component) 或者 dom 实例 在 stateNode 中.
A DIY guide to build your own React
This repository goes together with a series of posts that explains how to build React from scratch step by step.
Didact's goal is to make React internals easier to understand by providing a simpler implementation of the same API and step-by-step instructions on how to build it. Once you understand how React works on the inside, using it will be easier.
Medium Post | Code sample | Commits | Other languages |
---|---|---|---|
Introduction | |||
Rendering DOM elements | codepen | diff | 中文 |
Element creation and JSX | codepen | diff | 中文 |
Virtual DOM and reconciliation | codepen | diff diff diff | 中文 |
Components and State | codepen | diff | 中文 |
Fiber: Incremental reconciliation | codepen | diff diff | 中文 |
🚧 Don't use this for production code!
Install it with npm or yarn:
$ yarn add didact
And then use it like you use React:
/** @jsx Didact.createElement */
import Didact from 'didact';
class HelloMessage extends Didact.Component {
constructor(props) {
super(props);
this.state = {
count: 1
};
}
handleClick() {
this.setState({
count: this.state.count + 1
});
}
render() {
const name = this.props.name;
const times = this.state.count;
return (
<div onClick={e => this.handleClick()}>
Hello {name + "!".repeat(times)}
</div>
);
}
}
Didact.render(
<HelloMessage name="John" />,
document.getElementById('container')
);
hello-world
hello-world-jsx
todomvc
incremental-rendering-demo
MIT © Hexacta