ReactAntd(二) 后台准备下半部分

这里是后台搭建目录的后半部分

  • 安装 react-redux
  • 安装 axios
  • 安装 lottie
  • 网络加载加载

(一) 安装 react-redux

(1) 安装包依赖


yarn add redux -S

yarn add react-redux -S

(2) 在 src 目录下创建一个 store 文件夹 里面创建一个 index.js 文件作为公共仓库

  • 调试的时候要借助 redux 工具,store 里面必须要加入 window 开头的
import { createStore } from 'redux'
//引入reducer
import reducer from './reducer'
//放入reducer
const store = createStore(
  reducer,
  window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
)
export default store

(3) 在 src 目录下创建 actiontypes 文件

export const CHANGE_VALUE = 'change_value'
export const CLICK_CHANGE = 'click_change'
export const DELETE_ITEM = 'delete_item'

//正式的开始

export const CHANGE_LOADING = 'change_loading'

(4) 在 src 目录下面创建 actioncreater.js 文件

import {
  CHANGE_VALUE,
  CLICK_CHANGE,
  DELETE_ITEM,
  CHANGE_LOADING,
} from './actiontypes'

export const ACTION_CHANGE_VALUE = (value) => {
  return {
    type: CHANGE_VALUE,
    value,
  }
}

export const ACTION_CLICK_CHANGE = () => {
  return {
    type: CLICK_CHANGE,
  }
}

export const ACTION_DELETE_ITEM = (value) => {
  return {
    type: DELETE_ITEM,
    value,
  }
}

//正式的开始

export const ACTION_CHANGE_LOADING = (value) => {
  return {
    type: CHANGE_LOADING,
    value,
  }
}

(5)在 src 目录下创建 reducer.js 文件

  • 它里面接收两个参数(state,action)

  • state 就是获取所有的公共数据

import {
  CHANGE_VALUE,
  CLICK_CHANGE,
  DELETE_ITEM,
  CHANGE_LOADING,
} from './actiontypes'

const defaultState = {
  inputValue: '123',
  list: [
    'Racing car sprays burning fuel into crowd.',
    'Japanese princess to wed commoner.',
    'Australian walks 100km after outback crash.',
    'Man charged over missing wedding girl.',
    'Los Angeles battles huge wildfires.',
  ],
  loadingFlag: false,
}
export default (state = defaultState, action) => {
  //这里判断action的type然后在返回state
  if (action.type === CHANGE_VALUE) {
    let newresult = JSON.parse(JSON.stringify(state)) //必须要重新生成一个新的对象,也不能使用Object.asign这样有的时候不起作用,而且每个判断里面必须有返回值
    newresult.inputValue = action.value
    return newresult
  }
  if (action.type === CLICK_CHANGE) {
    let newData = JSON.parse(JSON.stringify(state))
    if (newData.inputValue != null) {
      newData.list.push(newData.inputValue)
      newData.inputValue = ''
    }
    return newData
  }
  // 这里就是删除方法,必须返回新数据
  if (action.type === DELETE_ITEM) {
    let newData = JSON.parse(JSON.stringify(state))
    newData.list.splice(action.value, 1)
    return newData
  }
  //----------正式开始------------
  if (action.type === CHANGE_LOADING) {
    let newData = JSON.parse(JSON.stringify(state))
    newData.loadingFlag = action.value
    return newData
  }
  return state
}

(6) 在 src 目录下面的 index.js 里面写

import React from 'react'
import ReactDOM from 'react-dom'
import './reset.css'
import RouterDom from './router.js'

import { Provider } from 'react-redux'
import store from './store/index'

ReactDOM.render(
  <Provider store={store}>
    <RouterDom />
  </Provider>,
  document.getElementById('root')
)

(7) 组件里面使用

  • 修改里面的变量即可
//必须要引入connect
import { connect } from 'react-redux'
//然后在类的外面定义两个常量,两个常量都是方法,返回的都是对象

const mapStateToProps = (state) => {
  return {
    inputValue: state.inputValue,
    list: state.list,
  }
}
const mapDispatchToProps = (dispatch) => {
  return {
    handleChange(e) {
      let value = e.target.value
      const action = {
        type: 'change_value',
        value,
      }
      dispatch(action)
    },
    changeList() {
      let action = {
        type: 'change_list',
      }
      dispatch(action)
    },
    deleteItem(index) {
      let action = {
        type: 'deleteItem',
        value: index,
      }
      console.log(index)
      dispatch(action)
    },
  }
}
//最后利用store挂钩

export default connect(
  mapStateToProps, //这里面放的是数据
  mapDispatchToProps //里面放的是操作的数据的方法
)(TodoList)

(二) 安装 lottie

(1) 安装包依赖


yarn add react-lottie -S

(2) 封装 lottie 核心组件

import React from 'react'
import Lottie from 'react-lottie'
import * as animationData from '../../utils/data.json'

export default class LottieControl extends React.Component {
  constructor(props) {
    super(props)
    this.state = { isStopped: false, isPaused: false }
  }

  render() {
    const loadingPosition = {
      position: 'fixed',
      left: '50%',
      top: '50%',
      marginLeft: '-250px',
      marginTop: '-250px',
      zIndex: 999,
    }

    const defaultOptions = {
      loop: true,
      autoplay: true,
      animationData: animationData.default,
      rendererSettings: {
        preserveAspectRatio: 'xMidYMid slice',
      },
    }

    return (
      <div>
        <Lottie
          options={defaultOptions}
          height={400}
          width={400}
          style={loadingPosition}
          isStopped={this.props.loadingFlag}
        />
      </div>
    )
  }
}

(3) 给核心组件套个壳子,属于 page

import React, { Component, Fragment } from 'react'
import LoadingComponent from '../components/Loading/loading.js'
import { connect } from 'react-redux'
class Loading extends Component {
  constructor(props) {
    super(props)
    this.state = {}
  }
  render() {
    const wrap = {
      width: '100vw',
      height: '100vh',
      position: 'fixed',
      top: '0px',
      bottom: '0px',
      background: 'rgba(0,0,0,0.7)',
    }

    return (
      <Fragment>
        <div style={wrap}>
          <LoadingComponent
            loadingFlag={this.props.loadingFlag}
          ></LoadingComponent>
        </div>
      </Fragment>
    )
  }
}

const mapStateToProps = (state) => {
  return {
    loadingFlag: state.loadingFlag,
  }
}
const mapDispatchToProps = (dispatch) => {
  return {}
}
//最后利用store挂钩

export default connect(
  mapStateToProps, //这里面放的是数据
  mapDispatchToProps //里面放的是操作的数据的方法
)(Loading)

(4) 页面上引用的时候必须放到 APP.js 里面

import React, { Component, Fragment } from 'react'
import Loading from './pages/Loading.js'
import { connect } from 'react-redux'
class App extends Component {
  constructor(props) {
    super(props)
    this.state = {
      message: '加载',
    }
  }
  render() {
    const { loadingFlag } = this.props
    return (
      <Fragment>
        {loadingFlag ? <Loading></Loading> : null}

        {this.props.children}
      </Fragment>
    )
  }
}

const mapStateToProps = (state) => {
  return {
    loadingFlag: state.loadingFlag,
  }
}
const mapDispatchToProps = (dispatch) => {
  return {}
}
//最后利用store挂钩

export default connect(
  mapStateToProps, //这里面放的是数据
  mapDispatchToProps //里面放的是操作的数据的方法
)(App)

(三) 安装 axios 封装 axios

(1) 安装包依赖


yarn add axios -S

(2) 封装 axios

  • window.location.href 后续替换

  • url 是区分不同环境加载不同配置文件的方法

  • 网络加载的时候改变 store 里面的值

// request.js
import axios from 'axios'
import store from '../store/index.js'
import { ACTION_CHANGE_LOADING } from '../store/actioncreaters'
import url from '../config.js'
/** **** request拦截器==>对请求参数做处理 ******/
axios.interceptors.request.use(
  (config) => {
    // 加载
    store.dispatch(ACTION_CHANGE_LOADING(true))
    let value = sessionStorage.getItem('token') || '123'
    if (value) config.headers.Authorization = value
    return config
  },
  (error) => {
    return Promise.reject(error)
  }
)
/** **** respone拦截器==>对响应做处理 ******/
axios.interceptors.response.use(
  (response) => {
    store.dispatch(ACTION_CHANGE_LOADING(false))
    return response
  },
  (error) => {
    // 错误提醒

    store.dispatch(ACTION_CHANGE_LOADING(false))
    const { status } = error.response
    if (status === 401) {
      // 清除token
      sessionStorage.clear()
      window.location.href = url.homeurl
    }
    if (status === 404) {
      window.location.href = url.homeurl
    }
    // 页面跳转
    //router.push('/login')

    return Promise.reject(error)
  }
)
export default axios

(四)到此后台搭建架构成型


文章作者: 雾烟云
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 雾烟云 !
  目录