- **Coroutine with Fiber** — This is an amazing idea, which implements the coroutine scheduler in JavaScript, and the rendering is asynchronous, which supports Time slicing and suspense components.
- **Highly-optimized algorithm** — Fre has a better reconciliation algorithm, which traverses from both ends with O (n) complexity, and supports keyed.
- **Do more with less** — After tree shaking, project of hello world is only 1KB, but it has most fetures, virtual DOM, hooks API, functional component and more.
### Use
```shell
yarn add fre
```
```js
import { h, render, useState } from 'fre'
function App() {
const [count, setCount] = useState(0)
return (
{count}
)
}
render(, document.getElementById('root'))
```
### Hooks API
- [useState](https://github.com/yisar/fre#usestate)
- [useEffect](https://github.com/yisar/fre#useeffect)
- [useReducer](https://github.com/yisar/fre#usereducer)
- [useLayout](https://github.com/yisar/fre#uselayout)
- [useCallback](https://github.com/yisar/fre#usecallback)
- [useMemo](https://github.com/yisar/fre#usememo)
- [useRef](https://github.com/yisar/fre#useref)
#### useState
`useState` is a base API, It will receive initial state and return a Array
You can use it many times, new state is available when component is rerender
```js
function App() {
const [up, setUp] = useState(0)
const [down, setDown] = useState(0)
return (
{up}
{down}
)
}
```
#### useReducer
`useReducer` and `useState` are almost the same,but `useReducer` needs a global reducer
```js
function reducer(state, action) {
switch (action.type) {
case 'up':
return { count: state.count + 1 }
case 'down':
return { count: state.count - 1 }
}
}
function App() {
const [state, dispatch] = useReducer(reducer, { count: 1 })
return (
{state.count}
)
}
```
#### useEffect
It is the execution and cleanup of effects, which is represented by the second parameter
```
useEffect(f) // effect (and clean-up) every time
useEffect(f, []) // effect (and clean-up) only once in a component's life
useEffect(f, [x]) // effect (and clean-up) when property x changes in a component's life
```
```js
function App({ flag }) {
const [count, setCount] = useState(0)
useEffect(() => {
document.title = 'count is ' + count
}, [flag])
return (
{count}
)
}
```
If it return a function, the function can do cleanups:
```js
useEffect(() => {
document.title = 'count is ' + count
return () => {
store.unsubscribe()
}
}, [])
```
#### useLayout
More like useEffect, but useLayout is sync and blocking UI.
```js
useLayout(() => {
document.title = 'count is ' + count
}, [flag])
```
#### useMemo
`useMemo` has the same rules as `useEffect`, but `useMemo` will return a cached value.
```js
function App() {
const [count, setCount] = useState(0)
const val = useMemo(() => {
return new Date()
}, [count])
return (
{count} - {val}
)
}
```
#### useCallback
`useCallback` is based `useMemo`, it will return a cached function.
```js
const cb = useCallback(() => {
console.log('cb was cached')
}, [])
```
#### useRef
`useRef` will return a function or an object.
```js
function App() {
useEffect(() => {
console.log(t) // { current:
t
}
})
const t = useRef(null)
return
t
}
```
If it use a function, It can return a cleanup and executes when removed.
```js
function App() {
const t = useRef(dom => {
if (dom) {
doSomething()
} else {
cleanUp()
}
})
return flag && I will removed
}
```
### Fragments
Fragments will not create dom element.
```jsx
<>someThing>
```
The above code needs babel plugin `@babel/plugin-transform-react-jsx`
```json
[
"@babel/plugin-transform-react-jsx",
{
"pragma": "h",
"pragmaFrag": "Fragment"
}
]
```
#### License
_MIT @yisar