当前位置: 首页 > 后端技术 > Node.js

实战react技术栈+express前后端博客项目(4)-- 博客首页代码的编写以及redux-saga的组织

时间:2023-04-03 17:20:48 Node.js

实战react技术栈+express前后端博客项目(四)——博客首页代码编写与redux-saga组织写完了会连载一个系列博客。随着开发的进行,确实遇到了很多坑,也请教了很多人。然后我想,为什么不在记录陷阱的同时分享收获。分享固然好,但如果能集思广益岂不更美。我们的口号是:坚决不做不完。本博客将为连载代码博客同步更新博客。以后随着项目的发展,可能会遇到之前写的不合适的地方,回去修改。如有不妥之处~欢迎兄弟们指教。谢谢!首页效果图(目前为假数据)未登录登录首页部分代码编写classHomeextendsComponent{constructor(props){super(props);this.shouldComponentUpdate=PureRenderMixin.shouldComponentUpdate.bind(this)}render(){const{login,register}=this.props;localStorage.setItem('userInfo',JSON.stringify(this.props.userInfo));返回(this.props.match.params.tag&&(tags.indexOf(this.props.match.params.tag)===-1||this.props.location.pathname.lastIndexOf('\/')>0)?:

{this.props.userInfo.userId?:}
)}}因为以后我们会使用标签作为路由来展示不同标签页面下的文章列表,所以当没有匹配到url,也没有匹配到相应的标签时,我们会显示404页面的首页部分,主要包括以下几项。轮播图(这里仅用于UI美化)、标签、文章列表、分页、登录功能。所以对于复杂编码的部分,我们单独提取组件。Home.js文件,点击所有标签对应的公共页面。只有文章列表不同。登录注册表单组件其他组件都是常规代码,这里先说表单组件classLoginFormComextendsComponent{constructor(props){super(props);}handleLogin=(e)=>{e.preventDefault();这。props.form.validateFields((err,values)=>{if(!err){this.props.login(values.userName,values.password)}});};render(){const{getFieldDecorator}=this.props.form;return({getFieldDecorator('userName',{rules:[{required:true,message:'请输入用户名!'}],})(}placeholder="Username"/>)}{getFieldDecorator('密码',{规则:[{required:true,message:'Pleaseenteryourpassword!'}],})(}type="密码"placeholder="Password"/>)}登录)}}constLoginForm=Form.create()(LoginFormCom);exportdefaultLoginForm这里我把登录和注册分开写了两个组件。具体写法可以参考antd官方文档。saga部分这部分所说的saga只是一些全局信息saga,包括错误信息提醒,全局Loading,登录状态等。并非首页文章列表标签的sagareducerconstinitialState={isFetching:true,msg:{type:1,//0失败1成功内容:''},userInfo:{}};exportconstactionsTypes={FETCH_START:"FETCH_START",FETCH_END:"FETCH_END",USER_LOGIN:"USER_LOGIN",USER_REGISTER:"USER_REGISTER",RESPONSE_USER_INFO:"RESPONSE_USER_INFO",SET_MESSAGE:"SET_MESSAGE",USER_AUTH:"USER_AUTH"};exportconstactions={get_login:函数(用户名,密码){return{type:actionsTypes.USER_LOGIN,username,password}},get_register:function(data){return{type:actionsTypes.USER_REGISTER,data}},clear_msg:function(){返回{type:actionsTypes.SET_MESSAGE,msgType:1、msgContent:''}},user_auth:function(){return{type:actionsTypes.USER_AUTH}}};exportfunctionreducer(state=initialState,action){switch(action.type){caseactionsTypes.FETCH_START:return{...state,isFetching:true};caseactionsTypes.FETCH_END:return{...state,isFetching:false};案例actionsTypes.SET_MESSAGE:return{...state,isFetching:false,msg:{type:action.msgType,content:action.msgContent}};caseactionsTypes.RESPONSE_USER_INFO:return{...state,userInfo:action.data};default:returnstate}}//constfront=combineReducers({////home//});exportdefaultcombineReducers({//front,globalState:reducer,admin})说下几个状态FETCH_START:“开始异步请求”,FETCH_END:异步请求结束,USER_LOGIN:“用户登录”,USER_REGISTER:“用户注册”,RESPONSE_USER_INFO:“收到登录信息”,SET_MESSAGE:“设置全局提醒”,USER_AUTH:"USER_AUTH"//后面没有登录,再说这个对应saga导出函数的处理*login(username,password){yieldput({type:IndexActionTypes.FETCH_START});try{returnyieldcall(post,'/user/login',{username,password})}catch(error){yieldput({type:IndexActionTypes.SET_MESSAGE,msgContent:'用户名或密码错误',msgType:0});}finally{yieldput({type:IndexActionTypes.FETCH_END});}}exportfunction*register(data){yieldput({type:IndexActionTypes.FETCH_START});try{returnyieldcall(post,'/user/register',data)}catch(error){yieldput({type:IndexActionTypes.SET_MESSAGE,msgContent:'注册失败',msgType:0});}finally{yieldput({type:IndexActionTypes.FETCH_END});}}exportfunction*loginFlow(){while(true){让请求t=yieldtake(IndexActionTypes.USER_LOGIN);letresponse=yieldcall(login,request.username,request.password);if(response&&response.code===0){yieldput({type:IndexActionTypes.SET_MESSAGE,msgContent:'登录成功!',msgType:1});yieldput({type:IndexActionTypes.RESPONSE_USER_INFO,data:response.data})}}}exportfunction*registerFlow(){while(true){让请求=yieldtake(IndexActionTypes.USER_REGISTER);letresponse=yieldcall(register,request.data);if(response&&response.code===0){yieldput({type:IndexActionTypes.SET_MESSAGE,msgContent:'注册成功!',msgType:1});yieldput({type:IndexActionTypes.RESPONSE_USER_INFO,data:response.data})}}}exportfunction*user_auth(){while(true){yieldtake(IndexActionTypes.USER_AUTH);尝试{yieldput({type:IndexActionTypes.FETCH_START});让回应=yieldcall(get,'/user/userInfo');if(response&&response.code===0){yieldput({type:IndexActionTypes.RESPONSE_USER_INFO,data:response.data})}}catch(err){console.log(err);}finally{yieldput({type:IndexActionTypes.FETCH_END});}}}saga主要处理用户登录和注册。每个saga处理函数需要放一个requeststart和requestEndedaction,如果request错误,需要设置全局状态提醒。user_auth是saga处理,后面不需要登录,后续介绍这里可以跳过。综上所述,在登录的时候,我们派发一个loginaction,saga会捕获这个action,经过相应的处理后,将相应的action放到reducer中。具体操作可以查看github上的代码。这部分主要是前端操作,所以代码部分在/app文件夹下。项目实现步骤系列博客实战React技术栈+快递前端博客项目(0)——预热一波实战React技术栈+快递前端博客项目(一)——整体项目结构搭建、状态状态树设计实战react技术栈+快递前后端博客项目(二)——前端react-xxx、路由配置实战react技术栈+快递前后端博客项目(3)——后端路由、代理、静态资源托管等配置说明实战react技术栈+快递前后端博客项目(4)——博客首页代码编写及redux-saga组织实战react技术栈+快递前后端博客项目(5)——登录功能前后端实现实战react技术栈+快递前后端博客项目(6)——使用session实现免登录+管理后台权限验证实战react技术栈+速递前后端博客项目(七)——前端管理界面用户查看功能+后端对应界面开发实战react技术栈+express前后端博客项目(8)——前端管理接口标签管理功能+后端对应接口开发实践react技术栈+express前后端博客项目(9)——前端管理界面评论管理功能+后端对应界面开发实战react技术栈+速递前后端博客项目(10)——前端管理界面发布文章功能实战react技术栈+express前后端博客项目(11)——增删改查后台界面对应文章部分实战react技术栈+express前后端博客项目(12))--发帖部分的前端改进(增删改查、分页等)实用react技术栈+express前后端博客项目(14)--内容详情页和页数的展示ofreadings实战react技术栈+express前后端博客项目(15)——博客添加评论功能及后端对应实现实战react技术栈+express前后端博客项目(16)--pm2说明React技术栈实战+express前后端博客项目(17)--收工如果有不懂的地方,或者需要和我交流,欢迎提出问题。或者加群联系我~扫码关注我的个人微信公众号,直接回复,必有回复。分享更多原创文章。点击交流学习加我微信和qq群。一起学习,一起进步欢迎兄弟加入:Node.js技术交流群:209530601React技术栈:398240621前端技术聊:604953717(新)