Skip to content

Repository files navigation

fre logo

Fre

👻 Tiny Concurrent UI library with Fiber.

GitHub LicenseBuild StatusCode Coveragenpm-vnpm-dbrotli

  • Concurrent Mode — This is an amazing idea, which implements the coroutine scheduler in JavaScript, it also called Time slicing.

  • Keyed reconcilation algorithm — Fre has a minimal diff algorithm, It supported keyed, pre-process, offscreen rendering and SSR hydration.

  • Do more with less — Fre get the tiny size, but it has most features, virtual DOM, hooks API, Suspense, Fragments, Fre.memo and so on.

Contributors

Usage

https://deepwiki.com/frejs/fre

yarn add fre
import{render,useState}from'fre'functionApp(){const[count,setCount]=useState(0)return<><h1>{count}</h1><buttononClick={()=>setCount(count+1)}>+</button></>}render(<App/>,document.body)

Features

Hooks API

useState

useState is a base API, It will receive initial state and return an 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(<><h1>{up}</h1><buttononClick={()=>setUp(up+1)}>+</button><h1>{down}</h1><buttononClick={()=>setDown(down-1)}>-</button></>)}

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(<>{state.count}<buttononClick={()=>dispatch({type: 'up'})}>+</button><buttononClick={()=>dispatch({type: 'down'})}>-</button></>)}

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(<><h1>{count}</h1><buttononClick={()=>setCount(count+1)}>+</button></>)}

If it returns a function, the function can do cleanups:

useEffect(()=>{document.title='count is '+countreturn()=>{store.unsubscribe()}},[])

useLayout

More like useEffect, but useLayout is sync and blocking UI.

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

useMemo

useMemo has the same rules as useEffect, but useMemo will return a cached value.

constmemo=(c)=>(props)=>useMemo(()=>c,[Object.values(props)])

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

useContext

import{createContext,useContext}from'fre';constThemeContext=createContext(null);functionApp(){return(<ThemeContextvalue="dark"><Button/></ThemeContext>)}functionButton({ children }){consttheme=useContext(ThemeContext);constclassName='button-'+theme;return(<buttonclass={className}>{children}</button>);}

Suspense

constHello=lazy('./hello.js')exportfunctionApp(){return(<div><Suspensefallback={<div>loading...</div>}><Hello/><div>world!</div></Suspense></div>)}

ErrorBoundary

functionA(){thrownewError('render error test')}exportfunctionApp(){return(<div><ErrorBoundaryfallback={<div>occur an error</div>}><A/></ErrorBoundary></div>)}

Fragments

// fragmentfunctionApp(){return<>{something}</>}// render arrayfunctionApp(){return[a,b,c]}

jsx

For vite example

exportdefault{esbuild: {jsxFactory: 'h',jsxFragment: 'Fragment',jsxInject: `import { h, Fragment } from 'fre'`,target: 'es2020',format: 'esm'}}

License

MIT @yisar

FOSSA Status

Releases

Sponsor this project

Packages

Used by

Contributors

Languages