基于webpack4搭建的react项目框架的方法
介绍
框架介绍,使用webpac构建的react单页面应用,集成antd。使用webpack-dev-server启动本地服务,加入热更新便于开发调试。使用bundle-loader进行代码切割懒加载
手动搭建,不使用cli,大量注释适合初学者对webpack的理解学习,对react项目的深入了解
启动
gitclonehttps://gitee.com/wjj0720/react-demo.git cdreact-demo yarn yarnstart
打包
yarnbuild
目录结构
+node_modules -src +asset +Layout +pages +redux +utils +app.js +index.html +index.js .babelrc package.json postcss.config.js webpack.config.js//webpack配置
bundle-loader懒加载使用
//webpack.config.js配置 module:{ rules:[ { test:/\.bundle\.js$/, use:{ loader:'bundle-loader', options:{ name:'[name]', lazy:true } } } ] } //页面引入组件 importHomefrom"bundle-loader?lazy&name=[name]!./Home"; //组件使用因为组件懒加载是通过异步的形式引入所以不能再页面直接以标签的形式使用需要做使用封装 importReact,{Component}from'react' import{withRouter}from'react-router-dom' classLazyLoadextendsComponent{ state={ LoadOver:null } componentWillMount(){ this.props.Loading(c=>{ this.setState({ LoadOver:withRouter(c.default) }) }) } render(){ let{LoadOver}=this.state; return( LoadOver?: 加载动画) } } exportdefaultLazyLoad //通过封装的懒加载组件过度增加加载动画
路由配置
框架按照模块划分,pages文件夹下具有route.js即为一个模块
//通过require.context读取模块下路由文件 constfiles=require.context('./pages',true,/route\.js$/) letrouters=files.keys().reduce((routers,route)=>{ letrouter=files(route).default returnrouters.concat(router) },[]) //模块路由文件格式 importUserfrom"bundle-loader?lazy&name=[name]!./User"; exportdefault[ { path:'/user', component:User }, { path:'/user/:id', component:User } ]
redux使用介绍
//---------创建-------- //为了不免action、reducer在不同文件来回切换对象的形式创建 //createReducer将书写格式创建成rudex认识的reducer exportfunctioncreateReducer({state:initState,reducer}){ return(state=initState,action)=>{ returnreducer.hasOwnProperty(action.type)?reducer[action.type](state,action):state } } //创建页面级别的store constUser_Info_fetch_Memo='User_Info_fetch_Memo' conststore={ //初始化数据 state:{ memo:9, test:0 }, action:{ asyncfetchMemo(params){ return{ type:User_Info_fetch_Memo, callAPI:{url:'http://stage-mapi.yimifudao.com/statistics/cc/kpi',params,config:{}}, payload:params } }, ... }, reducer:{ [User_Info_fetch_Memo](prevState={},{payload}){ console.log('reducer--->',payload) return{ ...prevState, memo:payload.memo } }, ... } } exportdefaultcreateReducer(store) exportconstaction=store.action //最终在模块界别组合[当然模块也有公共的数据(见Home模块下的demo写法)] import{combineReducers}from'redux' importinfofrom'./Info/store' exportdefaultcombineReducers({ info, 。。。 }) //最终rudex文件夹下的store.js会去取所有模块下的store.js组成一个大的store也就是我们最终仓库 //--------使用------ //首先在app.js中将store和app关联 import{createStore}from'redux' import{Provider}from'react-redux' //reducer即我们最终 importreducerfrom'./redux/store.js' //用户异步action的中间件 importmiddlewarefrom'./utils/middleware.js' letstore=createStore(reducer,middleware)。。。 //然后组件调用只需要在组件导出时候使用connent链接即可 importReact,{Component}from'react' import{connect}from'react-redux' //从页面级别的store中导出action import{action}from'./store' classDemoextendsComponent{ consthandle=()=>{ //触发action this.props.dispatch(action.fetchMemo({})) } render(){ console.log(this.props.test) return ss
关于redux中间件
//与其说redux中间件不如说action中间件 //中间件执行时机即每个action触发之前执行 // import{applyMiddleware}from'redux' importfetchProxyfrom'./fetchProxy'; //中间件是三个嵌套的函数第一个入参为整个store第二个为store.dispatch第三个为本次触发的action //简单封装的中间件没有对请求失败做过多处理目的在与项错误处理机制给到页面处理 constmiddleware=({getState})=>next=>asyncaction=>{ //此时的aciton还没有被执行 const{type,callAPI,payload}=awaitaction //没有异步请求直接返回action if(!callAPI)returnnext({type,payload}) //请求数据 constres=awaitfetchProxy(callAPI) //请求数据失败提示 if(res.status!==200)returnconsole.log('网络错误!') //请求成功返回data returnnext({type,payload:res.data}) } exportdefaultapplyMiddleware(middleware)
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。