zoukankan      html  css  js  c++  java
  • 【招聘App】—— React/Nodejs/MongoDB全栈项目:个人中心&退出登录

    前言:最近在学习Redux+react+Router+Nodejs全栈开发高级课程,这里对实践过程作个记录,方便自己和大家翻阅。最终成果github地址:https://github.com/66Web/react-antd-zhaoping,欢迎star。


    一、个人中心信息展示

    •  用户在登录后,authrouter.js中已经获取到所有的用户信息,并保存在redux;所以个人中心只需获取redux中的user数据即可

        

    • component目录下:创建user个人中心组件目录
      import React from 'react'
      import {Result, List, WhiteSpace, Button } from 'antd-mobile'
      import {connect} from 'react-redux'
      
      @connect(
          state => state.user
      )
      class User extends React.Component{
          render(){
              const props = this.props
              const Item = List.Item
              const Brief = Item.Brief
              // console.log(this.props)
              return props.user ? (
                  <div>
                      <Result 
                         img={<img src={require(`../img/${props.avatar}.png`)} style={{ 50}} alt=""/>}
                         title={props.user}
                         message={props.type=='boss' ? props.company :null}
                      />
                      <List renderHeader={()=>'简介'}>
                         <Item
                            multipleLine
                         >
                            {props.title}
                            {this.props.desc.split('
      ').map(v=><Brief key={v}>{v}</Brief>)}
                            {props.money ? <Brief>薪资:{props.money}</Brief> : null}
                         </Item>
                      </List>
                      <WhiteSpace />
                      <List>
                          <Item>退出登录</Item>
                      </List>
                  </div>
              ) : null
          }
      }
      
      export default User  

        

    二、退出登录

        清除cookie登录状态

    • 安装第三方插件browser-cookies
      npm install browser-cookies  --save 
    • 为【退出登录】的onClick事件监听this.logout方法

      <List>
           <Item onClick={this.logout}>退出登录</Item>
      </List>
      

      坑:antd-mobile的TabBar的div层会覆盖整个页面,导致这里的onClick事件失效,需要设置其z-index为-1

    • 使用Model弹框显示确认或取消‘退出登录’:通过browser-cookies的erase()清除cookie

      import browserCookie from 'browser-cookies'
      
      logout = () => {
      	const alert = Modal.alert
      
      	alert('注销', '确认退出登录吗???', [
      	      { text: '取消', onPress: () => console.log('cancel') },
      	      { text: '确认', onPress: () => {
      	         browserCookie.erase('userid')  //清除cookie
                    }}
             ])
      }
      

        清空redux数据  

    • 清除cookie后需要自动刷新页面:清空redux数据,让页面自动跳转到登录页
    • user.redux.js中:添加logout相关的reducer和action,将initState传入重置redux,并修改redirectTo为'/login'
      //actioin type
      const LOGOUT = 'LOGOUT'
      
      //reducer中添加
      case LOGOUT:
             return {...initState, redirectTo:'/login'}  
      
      //action
      export function logoutSubmit(){
          return {type:LOGOUT}
      }
    • user.js中:通过connect将redux中logoutSubmit方法传入组件

    1. 在清空cookie的同时清空redux数据,修改props中的redirectTo

    2. 判断props若没有user时,即用户没有登录或退出登录时,执行跳转

      import {logoutSubmit} from '../../redux/user.redux'
      
      @connect(
          state=>state.user,
          {logoutSubmit}
      )
      
      //alert确认后
      this.props.logoutSubmit()   //清空redux,并跳转到login页
      
      //判断没有props.user时
      <Redirect to={props.redirectTo} />

    • 坑:

    1. 原因:当前已经跳转到login页面,但还想跳转到/login路由时,会报上述错误

    2. 解决:login.js中修改跳转页面的判断条件,存在redirectTo且redirectTo不等于‘/login’时跳转

      {this.props.redirectTo&&this.props.redirectTo!=='/login' ? ……
      

        

    三、函数式编程

    • 高阶函数 :一个函数可以接受另一个函数作为参数,这样的函数称为高阶函数
      function hello(){
          console.log('hello everyOne I love react')
      }
      //高阶函数
      function WrapperHello(fn){
          return function(){
              console.log('before say hello')  
              fn()
              console.log('after say hello')
          }
      }
      hello = WrapperHello(hello)
      hello()
      

        

    四、高阶组件

        高阶组件:一个高阶组件是一个函数,它输入一个组件,然后返回一个新的组件

    • 组件会把属性转化成UI,而高阶组件会把一个组件转化成另外一个组件
    • 高阶组件最大的特点:重用组件逻辑
    • 它并不是由React API定义出来的功能,而是由React的组合特性衍生出来的一种设计模式
    • react-redux中的connect就是一个高阶组件
    • 高阶组件的使用
    1. 不要对原组件进行修改:对它们进行组合

    2. 惯例用法 : 将没有关系的属性 props 传递给所包装的组件

    3. 惯例用法 : 组合最大化

    4. 惯例用法 : 封装显示名称,便于调试

    • 使用警告:
    1. 不要在 render 方法内使用高阶组件

    2. 静态方法必须要复制

    3. Ref 没有被传递

        简单的高阶组件Demo  

    • 普通方式
      //组件就是一个函数
      class Hello extends React.Component{
          render(){
             return <h2>hello everyOne I love React</h2>
          }
      }
      //高阶组件基本功能:属性代理
      function WrapperHello(Comp){
          class WrapComp extends React.Component{
              render(){
                  return (
                      <div>
                          <p>这是HOC高阶组件特有的元素</p>
                          <Comp {...this.props}></Comp>
                      </div>
                  )
              }
          }
          return WrapComp
      }
      Hello = WrapperHello(Hello)
      

    • 装饰器方式:使用@包裹一层

      //高阶组件
      function WrapperHello(Comp){
          class WrapComp extends React.Component{
              render(){
                  return (
                      <div>
                          <p>这是HOC高阶组件特有的元素</p>
                          <Comp {...this.props}></Comp>
                      </div>
                  )
              }
          }
          return WrapComp
      }
      
      //装饰器方式:使用@包裹一层
      @wrapperHello
      class Hello extends React.Component{
          render(){
             return <h2>hello everyOne I love React</h2>
          }
      }
      

         使用高阶组件优化项目代码  

    • component目录下:创建imooc-form表单高阶组件目录,抽离出login和register表单复用的handlechange函数
      import React from 'react'
      
      export default function imoocForm(Comp){
          return class WrapperComp extends React.Component{
              constructor(props){
                  super(props)
                  this.state = {}
                  this.handleChange = this.handleChange.bind(this)
              }
      
              handleChange(key, val){
                  this.setState({
                      [key]: val
                  })
              }
      
              render(){
                  return <Comp handleChange={this.handleChange} state={this.state} {...this.props}></Comp>
              }
          }
      }
      
    • register.js中:使用@imoocForm包裹组件【login.js中同理】

    1. 在componentDidMount()中设置默认选择type为genius

    2. 此时组件中没有state和handleChange了,所有需要调用的时候都从this.props中获取

    3. 注意:@imoocForm必须在@connect后,connect也是高阶组件,参数为imoocForm返回的函数

      import imoocFrom from '../../component/imooc-form/imooc-form'
      
      @connect(
          state => state.user,
          {register}
      )
      @imoocFrom
      class Register extends React.Component{
          componentDidMount(){
              this.props.handleChange('type', 'genius')
          }
          handleRegister = () => {
              this.props.register(this.props.state)
          }
          //其它表单代码需要state和handleChange处都从this.props中获取

    注:项目来自慕课网

  • 相关阅读:
    [Mac] 获取cpu信息
    [gcc warnings] -Wtrigraph warnings
    查看SSD寿命
    [linux] 查看SATA速度和具体设备
    [raspberry p3] [suse] 安装maven
    文本处理例子
    容器中用shell脚本启动如何优雅关闭(传送kill SIGTERM信号)
    kubernetes deployment 使用镜像摘要发布新版本
    Yearning sql工单系统 自动执行工单python脚本
    Kubernetes 企业发行版、容器Pass平台 OpenShift4.3 规划裸机部署
  • 原文地址:https://www.cnblogs.com/ljq66/p/10281124.html
Copyright © 2011-2022 走看看