👻 Tiny React like framework with Concurrent.
- 🎉 Functional Component and hooks API
- 🎊 Time slicing and Algebraic effects
- 🔭 keyed reconcilation algorithm
Any other demos click here
yarn add freimport{h,render,useState}from'fre'functionApp(){const[count,setCount]=useState(0)return(<div><h1>{count}</h1><buttononClick={()=>setCount(count+1)}>+</button></div>)}render(<App/>,document.getElementById('root'))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
functionApp(){const[up,setUp]=useState(0)const[down,setDown]=useState(0)return(<div><h1>{up}</h1><buttononClick={()=>setUp(up+1)}>+</button><h1>{down}</h1><buttononClick={()=>setDown(down-1)}>-</button></div>)}useReducer and useState are almost the same,but useReducer needs a global reducer
functionreducer(state,action){switch(action.type){case'up':
return{count: state.count+1}case'down':
return{count: state.count-1}}}functionApp(){const[state,dispatch]=useReducer(reducer,{count: 1})return(<div>{state.count}<buttononClick={()=>dispatch({type: 'up'})}>+</button><buttononClick={()=>dispatch({type: 'down'})}>+</button></div>)}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
functionApp({ flag }){const[count,setCount]=useState(0)useEffect(()=>{document.title='count is '+count},[flag])return(<div><h1>{count}</h1><buttononClick={()=>setCount(count+1)}>+</button></div>)}If it return a function, the function can do cleanups:
useEffect(()=>{document.title='count is '+countreutn()=>{store.unsubscribe()}},[])More like useEffect, but useEffect queue in requestAnimationFrame, but useLayout is sync and block commitWork.
useLayout(()=>{document.title='count is '+count},[flag])useMemo has the same parameters as useEffect, but useMemo will return a cached value.
functionApp(){const[count,setCount]=useState(0)constval=useMemo(()=>{returnnewDate()},[count])return(<div><h1>{count} - {val}</h1><buttononClick={()=>setCount(count+1)}>+</button></div>)}useCallback is based useMemo, it will return a cached function.
constcb=useCallback(()=>{console.log('cb was cached')},[])useRef will return a function or an object.
functionApp(){useEffect(()=>{console.log(t)// { current:<div>t</div> }})constt=useRef(null)return<divref={t}>t</div>}If it use a function, It can return a cleanup and executes when removed.
functionApp(){constt=useRef(dom=>{if(dom){doSomething()}else{cleanUp()}})returnflag&&<spanref={t}>I will removed</span>}Fragments will not create dom element.
<>someThing</>The above code needs babel plugin @babel/plugin-transform-react-jsx
[
"@babel/plugin-transform-react-jsx",
{
"pragma": "h",
"pragmaFrag": "Fragment"
}
]Time slicing is the scheduling of reconcilation, synchronous tasks, sacrifice CPU and reduce blocking time
resumable exception is a concept of algebraic effects. It can synchronously throw effects and then resume the execution of other logic of components.
Fre implements a compact reconcilation algorithm support keyed, which also called diff.
It uses hash to mark locations to reduce much size.
_MIT @yisar
