:ghost: Tiny React16 like library with Concurrent and Suspense.
### Feature
- :tada: Functional Component and hooks API
- :confetti_ball: Concurrent and Suspense
- :telescope: keyed reconcilation algorithm
### Introduction
Fre (pronounced `/fri:/`, like free) is a tiny and perfect js library, It means [Free!](https://www.clicli.us/search/free) ~
| Package | Version | About |
| ---------------------------------------------------- | --------------------------------------------------- | --------------------- |
| [`Fre`](https://github.com/132yse/fre) |  | fre core |
| [`Fard`](https://github.com/132yse/fard) |  | mini-program with fre |
| [`use-routes`](https://github.com/132yse/use-routes) |  | router for fre |
### Demo
- [async rendering demo](https://codesandbox.io/s/suspicious-rosalind-i06mv)
- [key-based reconcilation demo](https://codesandbox.io/s/fre-demo-d7vm7)
- [suspense demo](https://codesandbox.io/s/fre-suspense-demo-h5nfy)
Thanks for [Rasmus Schultz](https://github.com/mindplay-dk)
### Use
```shell
yarn add fre
```
```js
import { h, render, useState } from "fre"
function Counter() {
const [count, setCount] = useState(0)
return (
{count}
)
}
render(, document.getElementById("root"))
```
### Hooks API
- [useState](https://github.com/132yse/fre#usestate)
- [useEffect](https://github.com/132yse/fre#useeffect)
- [useReducer](https://github.com/132yse/fre#usereducer)
- [useCallback](https://github.com/132yse/fre#usecallback)
- [useMemo](https://github.com/132yse/fre#usememo)
- [useRef](https://github.com/132yse/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 Counter() {
const [up, setUp] = useState(0)
const [down, setDown] = useState(0)
return (
{up}
{down}
)
}
render(, document.getElementById("root"))
```
#### 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 Counter() {
const [state, dispatch] = useReducer(reducer, { count: 1 })
return (
{state.count}
)
}
render(, document.getElementById("root"))
```
#### useEffect
`useEffect` takes two parameters, the first is a effect callback and the second is an array
if the array changed, the callback will execute after commitWork, such as `pureComponentDidUpdate`
if the array is empty, it means execute once, such as `componentDidMount`
if no array, it means execute every time , such as `componentDidUpdate`
if useEffect returns a function, the function will execute before next commitWork, such as `componentWillUnmount`
```js
function Counter({ flag }) {
const [count, setCount] = useState(0)
useEffect(() => {
document.title = "count is " + count
}, [flag])
return (
{count}
)
}
render(, document.getElementById("root"))
```
#### useCallback
`useCallback` has the same parameters as `useEffect`, but `useCallback` will return a cached function.
```js
const set = new Set()
function Counter() {
const [count, setCount] = useState(0)
const cb = useCallback(() => {
console.log("cb was cached")
}, [count])
set.add(cb)
return (
{set.size}
)
}
```
#### useMemo
`useMemo` has the same parameters as `useEffect`, but `useMemo` will return a cached value.
```js
function Counter() {
const [count, setCount] = useState(0)
const val = useMemo(() => {
return new Date()
}, [count])
return (
{count} - {val}
)
}
render(, document.getElementById("root"))
```
#### 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 exectes when removed.
```js
function App () {
const t = useRef(dom => {
console.log(dom) // span
return dom => {
console.log(dom) // null
}
})
return flag && I will removed
}
```
### props
Props are used for component communication
```js
function App() {
const [sex, setSex] = useState("boy")
return (
)
}
function Sex(props) {
return
{props.sex}
}
```
Props contains children to render all the child elements of itself
```js
const HelloBox = () => (
Hello world !
)
const Box = props =>
{props.children}
```
Hooks do not support HOC and extends, but render props are supported by default
```js
const HelloBox = () =>
{value}
} />
const Box = props =>
{props.render("hello world!")}
```
Also can be render children
```js
const HelloBox = () => (
{value => {
return