👻 Fast 1kB React like library with the same hooks API
- 🎉 really functionalComponent, hooks API, render props
- 🎊 Fiber Scheduler and hash keyed diff algorithm
- 🔭 minimal but wonderful , just 1 KB , no dependences
Fre (pronounced /fri:/
, like free) is a tiny and perfect js library, It means Free! ~
yarn add fre
import { h, render, useState } from 'fre'
function Counter() {
const [count, setCount] = useState(0)
return (
<div>
<h1>{count}</h1>
<button onClick={() => setCount(count + 1)}>+</button>
</div>
)
}
render(<Counter />, document.getElementById('root'))
react hooks API is a miracle, and fre will make it become a leading role
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
function Counter() {
const [up, setUp] = useState(0)
const [down, setDown] = useState(0)
return (
<div>
<h1>{up}</h1>
<button onClick={() => setUp(up + 1)}>+</button>
<h1>{down}</h1>
<button onClick={() => setDown(down - 1)}>-</button>
</div>
)
}
render(<Counter />, document.getElementById('root'))
useReducer
and useState
are almost the same,but useReducer
needs a global reducer
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 (
<div>
{state.count}
<button onClick={() => dispatch({ type: 'up' })}>+</button>
<button onClick={() => dispatch({ type: 'down' })}>+</button>
</div>
)
}
render(<Counter />, document.getElementById('root'))
useEffect
takes two parameters, the first is a effect callback and the second is an array, usually props
When the array changes, the effect callback will run after commitWork, such as pureComponentDidUpdate
if the array is empty, it means use once, such as componentDidMount
if the second is undefined, it means use every time , such as componentDidUpdate
function Counter({ flag }) {
const [count, setCount] = useState(0)
useEffect(() => {
document.title = 'count is ' + count
}, [flag])
return (
<div>
<h1>{count}</h1>
<button onClick={() => setCount(count + 1)}>+</button>
</div>
)
}
render(<Counter />, document.getElementById('root'))
useMemo
has the same parameters as useEffect
, but useMemo
will be ran immediately.
function Counter() {
const [count, setCount] = useState(0)
return (
<div>
<h1>{count}</h1>
<button onClick={() => setCount(count + 1)}>+</button>
{(useMemo(<Sex />), [])}
</div>
)
}
render(<Counter />, document.getElementById('root'))
Context is the state of external create, internal use
When it changes, all components that own useContext
will rerender
const ctx = createContext(0)
function App() {
const [count, setCount] = useContext(ctx)
return (
<div>
<h1>{count}</h1>
<button onClick={() => setCount(count + 1)}>+</button>
<Other />
</div>
)
}
function Other() {
const count = useContext(ctx)[0]
return <h1>{count}</h1>
}
functionalComponent is a new components scheme
function App() {
const [count, setCount] = useState(0)
return (
<div>
<h1>{count}</h1>
<button onClick={() => setCount(count + 1)}>+</button>
<Sex count={count} />
</div>
)
}
function Sex(props) {
const [sex, setSex] = useState('boy')
return (
<div>
<h2>{props.count}</h2>
<h1>{sex}</h1>
<button
onClick={() => {
sex === 'boy' ? setSex('girl') : setSex('boy')
}}
>
x
</button>
</div>
)
}
render(<App />, document.getElementById('root'))
Props are used for component communication
function App() {
const [sex, setSex] = useState('boy')
return (
<div>
<Sex sex={sex} />
<button
onClick={() => (sex === 'boy' ? setSex('girl') : setSex('boy'))}
/>
</div>
)
}
function Sex(props) {
return <div>{props.sex}</div>
}
Props contains children to render all the child elements of itself
const HelloBox = () => (
<Box>
<h1>Hello world !</h1>
</Box>
)
const Box = props => <div>{props.children}</div>
Hooks do not support HOC and extends, but render props are supported by default
const HelloBox = () => <Box render={value => <h1>{value}</h1>} />
const Box = props => <div>{props.render('hello world!')}</div>
Also can be render children
const HelloBox = () => (
<Box>
{value => {
return <h1>{value}</h1>
}}
</Box>
)
const Box = props => <div>{props.children('hello world!')}</div>
Fiber is a priority scheduling scheme.
It uses the traversal form of linked list to achieve time slicing
Fre implements a compact diff algorithm
It uses hash to mark locations for easy comparison
The default export h function needs to be configured
import { h } from 'fre'
{
"plugins": [["transform-react-jsx", { "pragma": "h" }]]
}
If it is a browser environment, recommend to use htm
Package | Version | About |
---|---|---|
Fre |
fre core | |
use-routes |
router for fre |
MIT ©132yse inspired by anu