day3--react-redux

一、认识高阶函数和高阶组件

day3--react-redux_第1张图片

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0gpKJOwy-1649342396303)(img/高阶函数.png)]

2.应用–可以增加原有组件没有的props

在这里面,把home类组件变成了高阶组件,并且给它增加了region这个属性

import React, { PureComponent } from 'react'

// 定义一个高阶函数
function enhanceComponent(WrappedComponent) {
  return class NewComponent extends PureComponent {
    render() {
      return 
    }
  }
}

class Home extends PureComponent {
  render() {
    return (
      

home: {`昵称${this.props.name} 年龄: ${this.props.age} 地区:${this.props.region}`}

) } } const EnhanceHome = enhanceComponent(Home) export default class App extends PureComponent { render() { return (
App
) } }

day3--react-redux_第2张图片

3.应用–高阶组件劫持context对象里面的数据,将其增加到相应组件的props里面

import React, { PureComponent, createContext } from 'react'

const userContext = new createContext({
  name: 'coderwhy',
  age: 18,
  region: '中国'
})
// 定义一个高阶函数
function enhanceComponent(WrappedComponent) {
  return class NewComponent extends PureComponent {
    render() {
      return 
    }
  }
}
// 因为给每一个组件都增加context属性很麻烦,所以可以使用高阶组件,将他们包裹,增加props
function WithUser(WrappedComponent) {
  return class NewComponent extends PureComponent{
    render() {
      return (
        
          {
            (user) => {
              return (
                
              )
            }
          }
        
      )
    }
  }
}
// class Home extends PureComponent {
//   render() {
//     return (
//       
//         {
//           (user) => {
//             return (
//               
//

home: {`昵称${user.name} 年龄: ${user.age} 地区:${user.region}`}

//
// ) // } // } //
// ) // } // } class Home extends PureComponent { render() { return (

home: {`昵称${this.props.name} 年龄: ${this.props.age} 地区:${this.props.region}`}

) } } // Home.contextType = userContext class About extends PureComponent { render() { return (

about: {`昵称${this.props.name} 年龄: ${this.props.age} 地区:${this.props.region}`}

) } } const UserHome = WithUser(Home) const UserAbout = WithUser(About) const EnhanceHome = enhanceComponent(Home) export default class App extends PureComponent { render() { return (

App

enhanceHome about&&home
) } }

4.应用–渲染判断鉴权—有点像路由守卫

day3--react-redux_第3张图片

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cQaT3edQ-1649342396306)(img/渲染判断鉴权.png)]

5.应用–生命周期劫持

利用高阶函数来劫持生命周期,在生命周期中来完成自己的逻辑

import React, { PureComponent } from 'react'
// 高阶组件
function getRenderTime(WrappedComponent) {
  // 这里只能用类组件,因为类组件里面可以使用this
  return class NewComponent extends PureComponent {
    UNSAFE_componentWillMount() {
      this.beginTime = Date.now()
    }
    componentDidMount() {
      this.endTime = Date.now()
      const interval = this.endTime - this.beginTime
      // 可以使用.name属性来获取组件名称
      console.log(WrappedComponent.name,' render时间: ', interval)
    }
    render() {
      return 
    }
  }
}
// 类组件
class Home extends PureComponent {
  render() {
    return (
      
Home
) } } // 函数组件 function About() { return (
About
) } const RenderTimeHome = getRenderTime(Home) const RenderTimeAbout = getRenderTime(About) export default class App extends PureComponent { render() { return (
) } }

6.高阶组件的意义

day3--react-redux_第4张图片

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pk9p8VqJ-1649342396308)(img/高阶函数的意义.png)]

二、组件其他内容补充

1.ref的转发

类组件上使用ref可以获得类组件上的state.props,refs,方法等信息

函数组件上不可以直接使用ref,会报错,需要使用react.forwardRef将这个函数组件包裹起来,这样的话,函数组件就可以有两个参数,第一个为props,接受父组件传过来的数据信息,第二个为ref,接受父组件传过来的ref信息,接受之后可以将它赋值给该函数组件上需要使用的元素,如下about组件里面赋值给了div元素

import React, { PureComponent, createRef, forwardRef } from 'react'

class Home extends PureComponent {
  constructor() {
    super()
    this.state = {
      counter: 0
    }
  }
  render() {
    return (
      
Home{this.state.counter}
) } } // function About() { // return ( //
// about //
// ) // } // forwardRef已经帮我们封装好了一个高阶组件, 有两个参数,可以帮助我们转发ref const About = forwardRef(function (props, ref) { return (
about
) }) export default class App extends PureComponent { constructor(props) { super(props) this.titleRef = createRef() this.homeRef = createRef() this.aboutRef = createRef() } render() { return (

hello world

{/* 函数组件不可以被赋予ref对象,并且ref不会被认为是props */}
) } printRef() { console.log(this.titleRef.current); console.log(this.homeRef.current); console.log(this.aboutRef.current); } }

2.React.Portals的使用

day3--react-redux_第5张图片

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HyOgsyA5-1649342396309)(img/Portals的使用.png)]

import React, { PureComponent } from 'react'
import ReactDOM from 'react-dom'

class Model extends PureComponent {
  render() {
    // 他的功能是将Model组件渲染到id为model的标签里面
    return ReactDOM.createPortal(this.props.children, document.getElementById('model'))
  }
}

export default class Home extends PureComponent {
  render() {
    return (
      

Home

Title

) } }

3.React.Fragment

day3--react-redux_第6张图片

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NrZ6IIyJ-1649342396310)(img/fragment的使用.png)]

4.React.StrictMode

day3--react-redux_第7张图片

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JKf72vMM-1649342396311)(img/严格模式.png)]

三、react中的css

1.react–css中出现的问题

day3--react-redux_第8张图片

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GzoZwvG5-1649342396312)(img/React中的css.png)]

2.内联样式

import React, { PureComponent } from 'react'

export default class App extends PureComponent {
  constructor() {
    super()
    this.pstyle = {
      color: 'orange',
      fontSize: '20px'
    }
  }
  render() {
    return (
      
{/* 内联样式必须是驼峰标识 */}

你好 react

{/* 可以在状态里面来维护样式 */}

你是最棒的!

) } }

day3--react-redux_第9张图片

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ojnABZrw-1649342396312)(img/内联样式.png)]

3.普通的css

很麻烦—会相互层叠

  • 普通的css我们通常会编写到一个单独的文件,之后再进行引入。

  • 这样的编写方式和普通的网页开发中编写方式是一致的:

    • 如果我们按照普通的网页标准去编写,那么也不会有太大的问题;
    • 但是组件化开发中我们总是希望组件是一个独立的模块,即便是样式也只是在自己内部生效,不会相互影响;
    • 但是普通的css都属于全局的css,样式之间会相互影响;
  • 这种编写方式最大的问题是样式之间会相互层叠掉;

4.css modules

1.给style文件命名必须是.module.css等,必须有module

2.引入之后,使用css必须在类名中使用,以{style.className}的方式来书写
day3--react-redux_第10张图片

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SHWQV3NY-1649342396313)(img/css modules.png)]

import React, { PureComponent } from 'react'
import homeStyle from './style.module.css'
export default class Home extends PureComponent {
  render() {
    return (
      
Home
) } }

5.css in js

day3--react-redux_第11张图片

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iti7uL6M-1649342396314)(img/css in js.png)]
day3--react-redux_第12张图片

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MvJcUUF2-1649342396315)(img/styled-components.png)]

5.1三个特点

import React, { PureComponent } from 'react'
import styled from 'styled-components'

/**
 * 特点:
 * 1.props穿透
 * 2.attrs的使用
 * 3.传入state作为props属性
*/
const IptStyle = styled.input.attrs({
  placeholder: 'Nihaoya',
  // 可以定义变量
  bcolor: 'blue',
})`
  background-color: pink;
  border-color: ${props => props.color}
`

export default class About extends PureComponent {
  constructor() {
    super()
    this.state = {
      color: 'red'
    }
  }
  render() {
    return (
      
) } }

5.2可以实现继承

import React, { PureComponent } from 'react'
import Home from '../home/index'
import About from '../about/index'
import appStyle from 'styled-components'
const AppWrapper = appStyle.div`
  font-size: 20px;
  color: pink;
`
const SButton = appStyle.button`
  padding: 10px 20px;
  color: white;
`
// 可以实现继承,padding和color属性继承自SButton
const SPrimaryButton = appStyle(SButton)`
  // padding: 10px 20px;
  // color: red;
  background-color: green;
`
export default class App extends PureComponent {
  render() {
    return (
        
          

app

app

我是普通的按钮 我是主要的按钮
) } }

5.3可以定制主题,这样就可以把公共的样式放在theme里面

Sdiv和input有相同的黄色

import React, { PureComponent } from 'react'
import styled, { ThemeProvider }  from 'styled-components'

/**
 * 特点:
 * 1.props穿透
 * 2.attrs的使用
 * 3.传入state作为props属性
*/
const IptStyle = styled.input.attrs({
  placeholder: 'Nihaoya',
  // 可以定义变量
  bcolor: 'blue',
})`
  background-color: pink;
  color:${props => props.theme.themeColor};
  border-color: ${props => props.theme.themeColor};
`
const Sdiv = styled.div`
  color: ${props => props.theme.themeColor}
`
export default class About extends PureComponent {
  constructor() {
    super()
    this.state = {
      color: 'red'
    }
  }
  render() {
    return (
      
        
        
        
          

about

) } }

6.在react中添加class

传入数组也可以
day3--react-redux_第13张图片

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KYlA75w5-1649342396315)(img/react中添加class.png)]

四、AntDesign组件库的使用

day3--react-redux_第14张图片

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LMQPYTIB-1649342396316)(img/介绍.png)]
day3--react-redux_第15张图片

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-l1SkQb5u-1649342396317)(img/兼容性.png)]

2.AntD安装

day3--react-redux_第16张图片

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-maIinAT2-1649342396317)(img/AntDesign的安装.png)]

3.认识craco-- 用来修改webpack中的配置

1.安装craco的库

2.修改package.json里面的js脚本

3.在项目根目录下增加craco.config.js的文件
day3--react-redux_第17张图片

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-S2aTte7e-1649342396318)(img/认识craco.png)]

3.1配置主题

day3--react-redux_第18张图片

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-t9m83bvc-1649342396319)(img/配置主题.png)]

3.2配置别名

day3--react-redux_第19张图片

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gbLK588D-1649342396319)(img/配置别名.png)]

4.书写案例

见代码,注意comment里面的actions是一个reactDOM数组

五、axios库的使用

1.前端网络请求的几种选择

day3--react-redux_第20张图片

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ehJ2E2dG-1649342396320)(img/网络请求几种方式.png)]

2.axios的基本使用

index.js文件里面

import App from './axios的使用/App'
// axios的基本配置
import axios from 'axios'
axios.defaults.baseURL = 'https://httpbin.org'
axios.defaults.timeout = 5000
// 设置全局默认的token
axios.defaults.headers.common['token'] = 'sasha'
// 只给post请求配置默认的token
axios.defaults.headers.post['token'] = 'sashapost'

请求拦截器

axios.interceptors.request.use(config => {
  // 1.发送网络请求时, 在界面中间显示loading的组件
  // 2.某一些请求需要用户携带token,如果没有携带,那么直接跳到登录页面
  // params和data序列化的操作
  config.headers.token = 'interceptor'
  return config
}, err => {
  return err
})

day3--react-redux_第21张图片

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-85jb0gOh-1649342396321)(img/axios的配置信息.png)]

3.axios的二次封装

day3--react-redux_第22张图片

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7roXeFnQ-1649342396322)(img/axios的二次封装.png)]

六、react过渡动画和纯函数的使用

1.react-transition-group介绍

day3--react-redux_第23张图片

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-awFARlIl-1649342396322)(img/react-transition-group.png)]

2.主要组件

day3--react-redux_第24张图片

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uq9fzsza-1649342396323)(img/react-transition-group组件.png)]

2.1、CSSTransition

1.将需要过渡动画的组件或者片段用包裹起来

2.给该标签添加三个属性

  • in:布尔值,用来控制元素隐藏和显示
  • timeout:用来控制过渡时间,单位毫秒,一定主要是number类型的,所以需要用花括号包裹,而不是引号
  • classNames:添加类名,定义相应的样式表
  • appear:布尔值,让其初次渲染的时候也有过渡动画,需要在css中设置相关动画
  • unmountOnExit:布尔值,让隐藏的时候dom元素消失
  • 常见钩子函数,见下面的图

组件

import React, { PureComponent } from 'react'

import { CSSTransition } from 'react-transition-group'
import { Card, Avatar, Button } from 'antd';
import { EditOutlined, EllipsisOutlined, SettingOutlined } from '@ant-design/icons';

// 引入css样式
import './CSSTranistion.css'

const { Meta } = Card;

export default class CSSTransitionDemo extends PureComponent {
  constructor() {
    super()
    this.state = {
      isShow: true
    }
  }
  render() {
    return (
      
{/*
*/} } actions={[ , , , ]} > } title="Card title" description="This is the description" /> {/*
*/}
) } changeShow() { this.setState({ isShow: !this.state.isShow }) } }

对应的样式

.card-enter, .card-appear{
  opacity: 0;
  transform: scale(0.6);
}
.card-enter-active, .card-appear-active{
  opacity: 1;
  transform: scale(1);
  transition: all 300ms;
}
/* .card-enter-done{

} */
.card-exit{
  opacity: 1;
  transform: scale(1);
}
.card-exit-active{
  opacity: 0;
  transform: scale(0.6);
  transition: all 300ms;
}
.card-exit-done{
  opacity: 0;
}

day3--react-redux_第25张图片

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3EF3GWE8-1649342396324)(img/CSSTransition.png)]

2.2、SwitchTransition

day3--react-redux_第26张图片

内容切换的时候需要使用的动画

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GyQs0BCg-1649342396324)(img/switchTransition.png)]

组件

import { Button } from 'antd'
import React, { PureComponent } from 'react'
import { SwitchTransition, CSSTransition } from 'react-transition-group'
import './SwitchTransition.css'

export default class SwitchTransitionDemo extends PureComponent {
  constructor() {
    super()
    this.state = {
      isOn: true
    }
  }
  render() {
    const { isOn } = this.state
    return (
      
{/* */}
) } }

css

.btn-enter{
  opacity: 0;
  transform: translateX(-100%);
}
.btn-enter-active{
  opacity: 1;
  transform: translateX(0);
  transition: opacity 2000ms, transform 2000ms;
}

.btn-exit{
  opacity: 1;
  transform: translateX(0);
}
.btn-exit-active{
  opacity: 0;
  transform: translateX(100%);
  transition: opacity 2000ms, transform 2000ms;
}

2.3、TransitionGroup

当我们有一组动画时,需要将这些CSSTransition放入到一个TransitionGroup中来完成动画:

组件

import { Button } from 'antd'
import React, { PureComponent } from 'react'
import { CSSTransition, TransitionGroup } from 'react-transition-group'
import './TransitionGroup.css'
export default class TransitionGroupDemo extends PureComponent {
  constructor(props) {
    super(props)
    this.state = {
      names: ['coderwhy', 'kobe', 'lilei']
    }
  }
  render() {
    return (
      
{ this.state.names.map((item, index) => { return (

{item}

) }) }
) } addName() { const newNames = [...this.state.names] newNames.push('lisa') this.setState({ names: newNames }) } }

css

.name-enter, .name-appear{
  opacity: 0;
  transform: scale(0.6);
}
.name-enter-active, .name-appear-active{
  opacity: 1;
  transform: scale(1);
  transition: all 1000ms;
}
.name-enter-done{
  color: pink;
}
.name-exit{
  opacity: 1;
  transform: scale(1);
}
.name-exit-active{
  opacity: 0;
  transform: scale(.6);
  transition: all 1000ms;
}
.name-exit-done{
  opacity: 0;
}

3.javascript纯函数

3.1含义

day3--react-redux_第27张图片

产生副作用的意思是修改了外部传过来的对象的值

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WMUp7WyX-1649342396325)(img/纯函数.png)]

3.2纯函数分析

day3--react-redux_第28张图片

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7v85mgTJ-1649342396326)(img/纯函数分析.png)]

七、redux的使用

1.为什么需要redux

day3--react-redux_第29张图片

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-h8Dfcvo2-1649342396327)(img/为什么需要redux.png)]

2.核心理念

2.1.store&action

day3--react-redux_第30张图片

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RxoxB0qq-1649342396327)(img/redux核心理念.png)]

2.2.reducer(类似vue的mutations)

day3--react-redux_第31张图片

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9EU0yx7J-1649342396328)(img/reducer.png)]

3.Redux的三大原则

day3--react-redux_第32张图片

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fNXX2j2u-1649342396329)(img/redux的三大原则.png)]

4.Redux测试项目搭建

day3--react-redux_第33张图片

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tvLSEgvg-1649342396329)(img/redux测试项目搭建.png)]

5.redux使用流程

day3--react-redux_第34张图片

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DZnAZ8tg-1649342396330)(img/Redux的使用流程.png)]

6.redux融入react

6.1自定义connect高阶函数–返回一个高阶组件

import { PureComponent } from 'react'
// import store from '../store/index'
import { StoreContext } from './context'

export function connect(mapStateToProps, mapDispatchToProp) {
  return function enhanceHOC(WrappedComponent) {
    class NewEnhanceComponent extends PureComponent {
      constructor(props, context) {
        super(props)
        this.state = {
          storeState: mapStateToProps(context.getState())
        }
      }
      // 订阅监听
      componentDidMount() {
        this.unsubscribe = this.context.subscribe(() => {
          this.setState({
            storeState: mapStateToProps(this.context.getState())
          })
        })
      }
      // 取消订阅
      componentWillUnmount() {
        this.unsubscribe()
      }
      render() {
        return <WrappedComponent
          {...mapStateToProps(this.context.getState())}
          {...mapDispatchToProp(this.context.dispatch)}
          {...this.props} />
      }
    }
    NewEnhanceComponent.contextType = StoreContext
    return NewEnhanceComponent
  }
}

// 返回一个高阶组件

在组件中使用connect函数–返回一个高阶组件,将组件的方法和状态都变成属性来使用

import React from 'react'
import { connect } from '../utills/connect.js'
import { subAction } from '../store/actionCreators'
function Home(props) {
  return (
    

home

当前计数: {props.counter}

) } const mapStateToProps = (state) => { return { counter: state.counter } }; const mapDispatchToProps = (dispatch) => { return { decrement: function() { return dispatch(subAction(1)) }, subNumber: function(num) { return dispatch(subAction(num)) } } }; export default connect(mapStateToProps, mapDispatchToProps)(Home)

6.2自定义context函数–目的是把connect中对store的依赖分离出来

import React from 'react'
export const StoreContext = React.createContext()

6.3context处理store

day3--react-redux_第35张图片

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nbumpRoX-1649342396330)(img/context处理store.png)]

import React from 'react';
import ReactDOM from 'react-dom';

import App from './04.redux的使用/App.js'
import store from './04.redux的使用/store/index'
import { StoreContext } from './04.redux的使用/utills/context'
// value值是必须的
ReactDOM.render(
  // 
  
      
  ,
  // ,
  document.getElementById('root')
);

八.组件中的异步操作—访问后台数据的时候,需要在组件生命周期函数中发起异步请求

import React, { PureComponent } from 'react'
// import { connect } from '../utills/connect.js'
import { connect } from 'react-redux'
import { subAction,changeBanners, changeRecommends } from '../store/actionCreators'

import axios from 'axios'
class Home extends PureComponent {
    // 发起异步请求
  componentDidMount() {
    axios({
      url: 'http://123.207.32.32:8000/home/multidata',
      method: 'get'
    }).then(res => {
      const data = res.data.data
      this.props.changeBanners(data.banner.list)
      this.props.changeRecommends(data.recommend.list)
    })
  }
  render() {
    return (
      

home

当前计数: {this.props.counter}

) } } const mapStateToProps = (state) => { return { counter: state.counter } }; const mapDispatchToProps = (dispatch) => { return { decrement: function() { return dispatch(subAction(1)) }, subNumber: function(num) { return dispatch(subAction(num)) }, changeBanners(banners) { dispatch(changeBanners(banners)) }, changeRecommends(recommends) { dispatch(changeRecommends(recommends)) } } }; export default connect(mapStateToProps, mapDispatchToProps)(Home)

用来访问后台数据,coderwhy老师的服务器http://123.207.32.32:8000/home/multidata
day3--react-redux_第36张图片

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zamgdynv-1649342396331)(img/redux中的异步操作.png)]

1.redux中的异步操作–redux-thunk的使用

需要使用中间件来操作,官方推荐redux-chunk

它的主要作用是将dispatch(action)中的action可以是一个函数来使用,因为我们之前的action默认是一个js对象

store/actionCreate.js

import { ADD_NUMBER, SUB_NUMBER, CHANGE_BANNER, CHANGE_RECOMMEND, FETCH_HOME_MULTIDATA } from "./constants.js"
import axios from 'axios'
export const addAction = function (num) {
  return {
    type: ADD_NUMBER,
    num: num
  }
}
export const subAction = function (num) {
  return {
    type: SUB_NUMBER,
    num: num
  }
}
// 轮播图和推荐的action
export const changeBanners = (banners) => {
  return {
    type: CHANGE_BANNER,
    banners: banners
  }
}
export const changeRecommends = (recommends) => {
  return {
    type: CHANGE_RECOMMEND,
    recommends: recommends
  }
}

// redux-thunk中的函数
export const getHomeMultidata = (dispatch) => {
  // console.log('redux-thunk');
  axios({
    url: 'http://123.207.32.32:8000/home/multidata',
    method: 'get'
  }).then(res => {
    const data = res.data.data
    dispatch(changeBanners(data.banner.list))
    dispatch(changeRecommends(data.recommend.list))
  })
}

// redux-saga拦截的action
export const fetchHomeMultidataAction = {
  type: FETCH_HOME_MULTIDATA
}

组件中的使用,其实还是在生命周期函数中调用

import React, { PureComponent } from 'react'
// import { connect } from '../utills/connect.js'
import { connect } from 'react-redux'
import { subAction,changeBanners, changeRecommends, getHomeMultidata } from '../store/actionCreators'

// import axios from 'axios'
class Home extends PureComponent {
  componentDidMount() {
    // axios({
    //   url: 'http://123.207.32.32:8000/home/multidata',
    //   method: 'get'
    // }).then(res => {
    //   const data = res.data.data
    //   this.props.changeBanners(data.banner.list)
    //   this.props.changeRecommends(data.recommend.list)
    // })
    this.props.getHomeMultidata()
  }
  render() {
    return (
      

home

当前计数: {this.props.counter}

) } } const mapStateToProps = (state) => { return { counter: state.counter } }; const mapDispatchToProps = (dispatch) => { return { decrement: function() { return dispatch(subAction(1)) }, subNumber: function(num) { return dispatch(subAction(num)) }, changeBanners(banners) { dispatch(changeBanners(banners)) }, changeRecommends(recommends) { dispatch(changeRecommends(recommends)) }, getHomeMultidata() { dispatch(getHomeMultidata) } } }; export default connect(mapStateToProps, mapDispatchToProps)(Home)

day3--react-redux_第37张图片

2.redux-devtools

1.浏览器下载edux-devtools插件

2.项目store/index.js配置中间件

import * as redux from 'redux'
import reducer from './reducer.js'

// 1.引入saga库
import createSagaMiddleware from 'redux-saga'
// 2.创建saga中间件
const sagaMiddleware = createSagaMiddleware()

// 3.应用一些中间件
// redux.applyMiddleware(中间件1, 中间件2, 中间件3)
const storeenhancer = redux.applyMiddleware(sagaMiddleware)
// composeEnhancer函数,使用redux-devtools
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || redux.compose;
const store = redux.createStore(reducer, composeEnhancers(storeenhancer))

// 4.开启saga中间件
sagaMiddleware.run(saga)

export default store

day3--react-redux_第38张图片

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DR53u7aS-1649342396333)(img/redux-devtools.png)]

3.generator

day3--react-redux_第39张图片

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vUHqSRkN-1649342396333)(img/es6-generator.png)]

4.redux-saga的使用

day3--react-redux_第40张图片

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8JXT9wF5-1649342396334)(img/redux-saga的使用.png)]

4.1配置redux-saga库

store/index.js

import * as redux from 'redux'
import reducer from './reducer.js'
import saga from './saga'

// 1.引入saga库
import createSagaMiddleware from 'redux-saga'
// 2.创建saga中间件
const sagaMiddleware = createSagaMiddleware()

// 3.应用一些中间件
// redux.applyMiddleware(中间件1, 中间件2, 中间件3)
const storeenhancer = redux.applyMiddleware(sagaMiddleware)
// composeEnhancer函数,使用redux-devtools
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || redux.compose;
const store = redux.createStore(reducer, composeEnhancers(storeenhancer))

// 4.开启saga中间件
sagaMiddleware.run(saga)

export default store

4.2定义actionCreate对象

// redux-saga拦截的action
export const fetchHomeMultidataAction = {
  type: FETCH_HOME_MULTIDATA
}

4.3定义saga函数

store/saga.js

import axios from 'axios'
import { FETCH_HOME_MULTIDATA } from './constants'
import { takeEvery, put, all } from 'redux-saga/effects'
import { changeBanners, changeRecommends } from './actionCreators'

function* fetchHomeMultidata(action) {
  const res = yield axios.get('http://123.207.32.32:8000/home/multidata')
  // // console.log(res);
  // yield put(changeBanners(res.data.data.banner.list))
  // yield put(changeRecommends(res.data.data.recommend.list))
  // 以下也可以,和上面一样的作用
  yield all([
    yield put(changeBanners(res.data.data.banner.list)),
    yield put(changeRecommends(res.data.data.recommend.list))
  ])
}

// 拦截每一个类型为FETCH_HOME_MULTIDATA的action,  并且执行fetchHomeMultidata这个生成器函数
function* mySaga() {
  // takeEvery(执行每一个)   takeLastest(只会执行最后一个)
  yield takeEvery(FETCH_HOME_MULTIDATA, fetchHomeMultidata)
}

// export default 生成器函数
export default mySaga

5.中间件的实现方式—后面看,没有时间了

coderwhy-react-17节:01:20:30暂停

6.reducer代码拆分

day3--react-redux_第41张图片

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3r2Bszql-1649342396335)(img/reducer代码拆分.png)]
day3--react-redux_第42张图片

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UstLKIPI-1649342396335)(img/combineReducer函数.png)]

九、状态管理方案

方案

1.组件内部自己维护state

2.redux

3.cintext上下文共享

推荐

  • ui相关的组件内部可以维护的状态,在组件自己的内部使用

  • 只要是需要共享的状态,都交给redux来处理’

  • 服务器请求过来的数据,交给redux处理

后续会补充的东西–项目中补充

redux和immutableJS结合使用

一些性能更新
``

4.3定义saga函数

store/saga.js

import axios from 'axios'
import { FETCH_HOME_MULTIDATA } from './constants'
import { takeEvery, put, all } from 'redux-saga/effects'
import { changeBanners, changeRecommends } from './actionCreators'

function* fetchHomeMultidata(action) {
  const res = yield axios.get('http://123.207.32.32:8000/home/multidata')
  // // console.log(res);
  // yield put(changeBanners(res.data.data.banner.list))
  // yield put(changeRecommends(res.data.data.recommend.list))
  // 以下也可以,和上面一样的作用
  yield all([
    yield put(changeBanners(res.data.data.banner.list)),
    yield put(changeRecommends(res.data.data.recommend.list))
  ])
}

// 拦截每一个类型为FETCH_HOME_MULTIDATA的action,  并且执行fetchHomeMultidata这个生成器函数
function* mySaga() {
  // takeEvery(执行每一个)   takeLastest(只会执行最后一个)
  yield takeEvery(FETCH_HOME_MULTIDATA, fetchHomeMultidata)
}

// export default 生成器函数
export default mySaga

5.中间件的实现方式—后面看,没有时间了

coderwhy-react-17节:01:20:30暂停

6.reducer代码拆分

day3--react-redux_第43张图片

[外链图片转存中…(img-3r2Bszql-1649342396335)]
day3--react-redux_第44张图片

[外链图片转存中…(img-UstLKIPI-1649342396335)]

九、状态管理方案

方案

1.组件内部自己维护state

2.redux

3.cintext上下文共享

推荐

  • ui相关的组件内部可以维护的状态,在组件自己的内部使用

  • 只要是需要共享的状态,都交给redux来处理’

  • 服务器请求过来的数据,交给redux处理

后续会补充的东西–项目中补充

redux和immutableJS结合使用

一些性能更新

你可能感兴趣的:(前端,reactjs)