Repository: tranbathanhtung/react-fiber-implement
Branch: master
Commit: 02970bea916e
Files: 41
Total size: 84.3 KB
Directory structure:
gitextract_sdllfs4y/
├── .babelrc
├── .flowconfig
├── .gitignore
├── README.md
├── index.html
├── index.js
├── package.json
├── src/
│ ├── core/
│ │ ├── h.js
│ │ ├── life-cycle.js
│ │ └── with-state.js
│ ├── dom/
│ │ ├── config.js
│ │ ├── constants.js
│ │ ├── index.js
│ │ └── utils/
│ │ ├── append.js
│ │ ├── createElement.js
│ │ ├── getDocumentByElement.js
│ │ ├── insert.js
│ │ ├── remove.js
│ │ ├── textElement.js
│ │ └── validate.js
│ ├── fiber/
│ │ ├── begin-work.js
│ │ ├── children.js
│ │ ├── commit-work.js
│ │ ├── complete-work.js
│ │ ├── f-life-cycle.js
│ │ ├── f-node.js
│ │ ├── f-with.js
│ │ ├── host-context.js
│ │ ├── reconciler.js
│ │ ├── root-render.js
│ │ ├── scheduler.js
│ │ └── stack.js
│ ├── shared/
│ │ ├── effect-tag.js
│ │ ├── shallowEqual.js
│ │ ├── status-work.js
│ │ ├── tag.js
│ │ ├── types.js
│ │ ├── validate.js
│ │ └── with-effect.js
│ └── structures/
│ └── linked-list.js
└── webpack.config.js
================================================
FILE CONTENTS
================================================
================================================
FILE: .babelrc
================================================
{
"plugins": [
"transform-react-jsx",
"@babel/plugin-proposal-class-properties",
],
"presets": [
"@babel/flow",
"@babel/preset-env",
"@babel/preset-react"
]
}
================================================
FILE: .flowconfig
================================================
[ignore]
[include]
[libs]
[lints]
[options]
[strict]
================================================
FILE: .gitignore
================================================
# dependencies
/node_modules
yarn.lock
================================================
FILE: README.md
================================================
## React fiber
react-fiber is my self-study project help me understand how react work. In fact, all codebase re-implement each step , so it looks similar to the source code of react. Though, I think it's still smaller and easier to understand than when you actually read the react source code. I hope it helpful for people who want to start learn how react fiber work.
## Something you should read and learn before start read source code
#### Keyword, Algorithms and Data Structure Used
- Single linked list, Circular linked list
- Simple stack and queue
- Recursive
- Structural sharing
- [Reconciliation](https://reactjs.org/docs/reconciliation.html)
- Scheduler
- Bitwise Operators
- JSX
- DOM
###### And more
- [React Components, Elements, and Instances](https://reactjs.org/blog/2015/12/18/react-components-elements-and-instances.html)
- [Design Principles](https://reactjs.org/docs/design-principles.html)
- [React Fiber resources](https://github.com/koba04/react-fiber-resources)
- [The how and why on React’s usage of linked list in Fiber to walk the component’s tree](https://medium.com/react-in-depth/the-how-and-why-on-reacts-usage-of-linked-list-in-fiber-67f1014d0eb7)
- [In-depth explanation of state and props update in React
](https://medium.com/react-in-depth/in-depth-explanation-of-state-and-props-update-in-react-51ab94563311)
###### Recommend
- [Lin Clark - A Cartoon Intro to Fiber - React Conf 2017
](https://www.youtube.com/watch?v=ZCuYPiUIONs)
- [A look inside React Fiber
](https://makersden.io/blog/look-inside-fiber/)
- [Build your own React Fiber](https://engineering.hexacta.com/didact-fiber-incremental-reconciliation-b2fe028dcaec)
- [React Fiber Architecture @acdlite](https://github.com/acdlite/react-fiber-architecture) and [React Fiber Architecture @SaeedMalikx](https://github.com/SaeedMalikx/React-Fiber-Architecture)
## Overview
### Fiber tree

[Inside Fiber: in-depth overview of the new reconciliation algorithm in React](https://medium.com/react-in-depth/inside-fiber-in-depth-overview-of-the-new-reconciliation-algorithm-in-react-e1c04700ef6e)
### Keyword
```
work (unitOfWork): A component, node element => fiber
current: Current fiber what is displayed on browser
WIP (workInProgress): New fiber tree we will build
fiber: {
type: string | Function ('div', 'span', function Button)
instanceNode: HTMLElement (div, span)
return: fiber (parent of fiber)
child: fiber (child of fiber)
sibling: fiber (sibling of fiber)
alternate: link current - WIP and WIP - current
effectTag: number (give we know what will happen this fiber)
}
requestIdleCallback
main function:
createWorkInProgress()
beginWork()
reconcileChildren()
completeWork()
commitWork()
```
### Process of first render
```
Render -> Reconciler -> Scheduler ->
Begin Work (build fiber tree) -> ChildReconciler(create child and effectTag) -> if work has child we will continue to run beginWork -> no child ->
Complete Work (build list effect, mark tag and create instanceNode) -> sibling has child -> turn back Begin Work -> no child -> Complete Work -> no sibling -> has a new tree with effect tag ->
Commit Work : It will base on list effect tag to commit each fiber (Placement, Update, Delete, Lifecycle)
// In first render current fiber is null.
// current is workInProgress when commit
```
### Process when update
```
Do something ->
Get current Fiber what corresponding to the component ->
Recursive to find Root ->
Clone fiber from root to component has update ->
Begin Work from this fiber (it's maybe clone fiber when children of component use memo, pure component or use shouldComponentUpdate) ->
Complete Work ->
Commit Work
```
### About With(Hook v16.7)
```
Hooks are stored as a linked list on the fiber's prevState field of fiber.
current tree - current hook <=> WIP - WIP hook
```
================================================
FILE: index.html
================================================
================================================
FILE: index.js
================================================
/** @jsx h */
import { h } from './src/core/h';
import { withState } from './src/core/with-state';
import { lifeCycle } from './src/core/life-cycle';
import { render } from './src/dom';
let list = []
for (let i = 0; i < 5; i++) {
list = [
...list,
{
name: 'tung',
age: 10,
id: i,
}
]
}
const User = ({ user, update, remove }) => {
lifeCycle({
mounted() {
console.log('mounted User')
return () => console.log('unmounted User')
}
})
return (