Skip to content

Repository files navigation

fre logo

Fre

👻 Tiny React like framework with Concurrent.

Build StatusCode Coveragenpm-vnpm-dbrotli

Feature

  • 🎉 Functional Component and hooks API
  • 🎊 Time slicing and Algebraic effects
  • 🔭 keyed reconcilation algorithm

Real world

clicli.me

Any other demos click here

Use

yarn add fre
import{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'))

Hooks API

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

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

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>)}

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
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()}},[])

useLayout

More like useEffect, but useEffect queue in requestAnimationFrame, but useLayout is sync and block commitWork.

useLayout(()=>{document.title='count is '+count},[flag])

useMemo

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

useCallback is based useMemo, it will return a cached function.

constcb=useCallback(()=>{console.log('cb was cached')},[])

useRef

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

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

Time slicing is the scheduling of reconcilation, synchronous tasks, sacrifice CPU and reduce blocking time

resumable exception

resumable exception is a concept of algebraic effects. It can synchronously throw effects and then resume the execution of other logic of components.

key-based reconcilation

Fre implements a compact reconcilation algorithm support keyed, which also called diff.

It uses hash to mark locations to reduce much size.

License

_MIT @yisar

About

👻 Tiny React16 like framework with Concurrent.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages