Skip to content

Repository files navigation

wolverine

a lightweight react framework based on react 、redux and middleware

  • 约束原则

    • 采用分层原则,职责分离
    • controller 与 view 一一对应,处理相应的业务逻辑
    • redux store 中只维护业务数据实体
    • 视图交互相关的 state 维护在 controller
    • effects 应该维护在相应的 controller
    • 不应该 dispatch 异步 action
  • 更多请看这里关于框架分层设计的思考

intro

framework

  • model
    • reducers:维护与服务端一致的数据实体
  • controller
    • controller:是一个自定义 hook,无需考虑复用,因为 controller 与 view 一一对应
    • event binding
    • hook
    • effect
    • dispatch sync action
    • store selector
  • view
    • 与 controller 一一对应,保持 view 的简单性
  • application
    • router config
    • redux config
    • app life cycle
    • middlewares:支持同步或异步中间件。
      • jsb sdk
      • report sdk
      • error sdk
      • perf sdk
      • ...
  • fetch controller:缓存,http 规范,错误处理等
    • middleware
      • fetch error
      • before fetch
      • after fetch
    • sw fetch cache
  • base
    • hooks:通用 hook
    • components:通用组件
    • middleware plugins

install

yarn add @jarzzzi/wolverine

quick start

demo

  • index
constapp=newWolverine({appMode: 'spa',routerMode: 'hashRouter'})app.configReducers(reducers)app.configRoutes(routes)app.onError((error,ctx)=>{console.log('app error',error)})app.onDidmount((ctx)=>{console.log('app didmount',ctx)consthandle=(state: any)=>{console.log('route change',state)}constcleanup=ctx.on('routeChange',handle)return()=>{cleanup()}})app.onUnmount((ctx)=>{console.log('app unmount',ctx)})app.use((ctx)=>{returnimport('./plugins/reportsdk').then(({default: reporter})=>{ctx.reporter=reporterreturn()=>{console.log('cleanup reporter')}})})app.render(document.getElementById('root'))
  • reducer
exportdefaultcreateModel({namespace: 'counter',state: {count: 0},reducers: {inc(state,{payload: count}){return{
...state,count: count}},dec(state,{payload: count}){return{
...state,count: count}},fetch(state,{payload: count}){return{
...state,count: count}}},})
  • controller
exportdefaultfunctionuseController(props){const[loading,setLoading]=useState(false)constdispatch=useDispatch()const{ count }=useSelector((store)=>{const{ counter }=storereturn{count: counter.count}})constonInc=()=>{dispatch({type: 'counter/inc',payload: count+1})}constonDec=()=>{dispatch({type: 'counter/dec',payload: count-1})}constonFetch=async()=>{setLoading(true)constres=awaitfetch('xxx')setLoading(false)dispatch({type: 'counter/fetch',payload: res})}constonReport=async()=>{appContext.ready('reporter').then((reporter)=>{reporter.push()})}return{
count,
onInc,
onDec,
onFetch,
onReport
}}
  • view
exportdefaultReact.memo((props)=>{const{
count,
onDec,
onInc,
onFetch,
onReport,}=useController(props)return(<div><div>{count}</div><div><buttononClick={onInc}>inc</button></div><div><buttononClick={onDec}>dec</button></div><div><buttononClick={onFetch}>fetch</button></div><div><buttononClick={onReport}>report</button></div></div>)})

next

  • immutable data

About

a lightweight react framework based on react and redux

Topics

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages