redux react-redux redux-thunk

1. 理解redux

redux是一个独立专门用来做状态管理的js库(不是react插件库);

作用: 集中式管理react应用中多个组件共享的状态

2. 工作流程

在这里插入图片描述

3. 核心API

(1) createStore() : 创建包含指定reducer的store对象

(2) store对象: redux库最核心的管理对象; 将state,action与reducer联系在一起的对象

store.getState(): 得到state
store.dispatch(action): 分发action, 触发reducer调用, 产生新的state
store.subscribe(listener): 注册(订阅)监听, 一旦状态发生改变, 自动重新渲染

(3) action : 标识要执行行为的对象;获取异步数据
包含2个方面的属性:
type: 标识属性, 值为字符串, 唯一, 必要属性
xxx: 数据属性, 值类型任意, 可选属性

(4) reducer:根据老的state和action, 产生新的state的纯函数
a.返回一个新的状态
b.不要修改原来的状态

4. 安装

npm install --save redux

5. 案例

(1)创建store对象

// redux/store.js
import {createStore} from 'redux'
import {counter} from './reducer'

// 生成一个store对象 (接受reducer)
const store = createStore(counter)

export default store

(2)reducer

// redux/reducer.js
/*
根据老的state和指定action, 处理返回一个新的state
 */
 // 导入常数
import {INCREMENT, DECREMENT} from './action_types'


export function counter(state = 0, action) {
  // console.log('counter', state, action)
  switch (action.type) {
    case INCREMENT:
      return state + action.number
    case DECREMENT:
      return state - action.number
    default:
      return state
  }
}

(3) action

// redux/action.js
// action creator

import {INCREMENT, DECREMENT} from  './action_types'

export const increment = number => ({type: INCREMENT, number})
export const decrement = number => ({type: DECREMENT, number})

(4) 常量

// redux/action_types.js
// action 常量的名称模块

export const INCREMENT = 'increment'

export const DECREMENT = 'decrement'

(5)index.js 文件

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';

import store from  './redux/store'


// 定义渲染根组件标签的函数
const render = () => {
  ReactDOM.render(
    <App store={store}/>,
    document.getElementById('root')
  )
}
// 初始化渲染
render()

// 注册(订阅)监听, 一旦状态发生改变, 自动重新渲染
store.subscribe(render)

(6)app.js


import React, { Component } from 'react';

import * as actions from './redux/action'

class App extends Component {

  increment = ()=>{
    // 分发action,触发reducer调用,产生新的state
    this.props.store.dispatch(actions.increment(1))
  }

  decrement = ()=>{
    this.props.store.dispatch(actions.decrement(1))
  }

  render() {
    return (
      <div>
          <p>  {this.props.store.getState()}  </p>
          <div>
            <button onClick={this.increment}> + </button>
            <button onClick={this.decrement}> - </button>
          </div>
      </div>
    );
  }
}

export default App; 

问题:

  1. redux 与 react 组件的代码耦合度太高
  2. 编码不够简洁
6. react-redux

npm install --save react-redux

一个react插件库,专门用来简化react应用中使用redux

react-redux将所有组件分成两大类:UI组件 和 容器组件

  1. UI 组件 :只负责 UI 的呈现,不带有任何业务逻辑 ; 通过 props 接收数据(一般数据和函数) ; 不使用任何 Redux 的 API ; 一般保存在 components 文件夹下。
  2. 容器组件 : 负责管理数据和业务逻辑,不负责 UI 的呈现 ; 使用 Redux 的 API ; 一般保存在 containers 文件夹下
7. react-redux 相关API
  1. Provider
    让所有组件都可以得到 state 数据
<Provider store={store}> <App /> </Provider>
  1. connect()
    将UI组件包装成容器组件;链接react 与redux
    state 返回一个对象
export default connect(
    state => ({user: state.user}),
    {updateUserInfo}
)(DashenInfo);
  1. mapStateToprops()
    将 外部state(store仓库里的数据,也就是异步获取的数据) 转换为 UI 组件的标签属性;作为props绑定到组件上
export default connect(
    state => ({user: state.user}),
    {updateUserInfo}
)(DashenInfo);
  1. mapDispatchToProps()
    将action作为props绑定到组件上 ,简洁语法可以直接指定为 actions 对象或包含多个 action 方法的对象
8. 案例改写

(1)components/counter.js

// UI 组件  不包含任何reduxAPI

import React, {Component} from 'react';

class Counter extends Component {

    increment  = ()=>{
        this.props.increment(1)
    };

    decrement  = ()=>{
        this.props.decrement(1)
    };
    render() {
        console.log(this);
        return (
            <div>
                <p> {this.props.count} </p>
                <div>
                    <button onClick={this.increment}> + </button>
                    <button  onClick={this.decrement}> - </button>
                </div>
            </div>
        );
    }
}


export default Counter

(2)containers/App.js


// 包含counter组件的容器组件

import React from 'react';
// 链接react-redux  redux
import {connect} from 'react-redux'
import {increment, decrement} from '../redux/action'
import Counter from "../components/Counter";


export default connect(
    state =>(
        {count:state}
    ),{increment, decrement}

)(Counter);

(3)redux 文件j夹 内容不变

(4)index.js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './containers/App';

import {Provider} from 'react-redux'

import store from './redux/store'

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

问题: redux 默认是不能进行异步处理

9. redux-thunk 异步编程(优先使用)

redux 异步中间件
npm install --save redux-thunk

10. 案例改写

(1)component/counter.js

// UI 组件  不包含任何reduxAPI

import React, {Component} from 'react';

class Counter extends Component {

  increment  = ()=>{
  // 新增异步方法
      this.props.incrementAsync(1)
  };

  decrement  = ()=>{
      this.props.decrement(1)
  };
  render() {
      console.log(this);
      return (
          <div>
              <p> {this.props.count} </p>
              <div>
                  <button onClick={this.increment}> + </button>
                  <button  onClick={this.decrement}> - </button>
              </div>
          </div>
      );
  }
}


export default Counter

(2)app.js


// 包含counter组件的容器组件

import React from 'react';
// 链接react-redux  redux
import {connect} from 'react-redux'
import {increment, decrement, incrementAsync} from '../redux/action'
import Counter from "../components/Counter";


export default connect(
  state =>(
      {count:state}
  ),{increment, decrement, incrementAsync}

)(Counter);

(3) store.js

import {createStore, applyMiddleware}  from 'redux'
import thunk from 'redux-thunk'
import {counter} from  './reducer'


export default createStore(counter, applyMiddleware(thunk))

(4) action.js

export const increment = number => ({type: 'increment', number});
export const decrement = number => ({type: 'decrement', number});

export const incrementAsync = number =>{
  return dispatch =>{
      setTimeout(()=>{
          dispatch(increment(number))
      }, 1000)
  }
};

11. 使用总结

(1)模块安装
npm i --save redux react-redux redux-thunk

(2)创建文件夹

在这里插入图片描述

reducer.js

/*
    包含多个用于生成新的state的reducer函数的模块
 */

import {combineReducers} from 'redux'

function xxx(state=0, action) {
    return state
}

function yyy(state=0, action) {
    return state
}

export default combineReducers({
    xxx,yyy
})

index.js


import React from 'react';
import ReactDOM from 'react-dom';
import App from './app'
import {BrowserRouter} from 'react-router-dom'
import 'antd/dist/antd.css';
import {Provider} from 'react-redux'
import store from './redux/store'

ReactDOM.render(
    <Provider store={store}>
        <BrowserRouter>
            <App></App>
        </BrowserRouter>
    </Provider>

    ,
    document.getElementById('root')
);


store.js

/*
    redux最核心的store对象模块
 */

import {createStore, applyMiddleware} from 'redux'
import thunk from 'redux-thunk'

import reducers from './reducer'

export default createStore(reducers, applyMiddleware(thunk))

ui 组件封装成容器组件

import {connect} from 'react-redux'

export default connect(
    state=>({state: state}),
    {}
)(Right);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: React-saga和React-thunk都是用于处理异步操作的中间件。 React-thunkRedux官方推荐的中间件之一,它允许我们在Redux中编写异步操作,使得我们可以在Redux中处理异步操作,而不需要在组件中处理异步操作。Thunk是一个函数,它接收dispatch和getState作为参数,并返回一个函数,这个函数接收dispatch作为参数,并在异步操作完成后调用dispatch。 React-saga是另一个处理异步操作的中间件,它使用了ES6的Generator函数来处理异步操作。Saga使用了一种称为Effect的概念,它是一个简单的JavaScript对象,用于描述异步操作。Saga使用了一种称为yield的语法,它允许我们在Generator函数中暂停异步操作,并在异步操作完成后继续执行。 总的来说,React-thunk和React-saga都是用于处理异步操作的中间件,它们的实现方式不同,但都可以让我们在Redux中处理异步操作。选择哪种中间件取决于个人的喜好和项目的需求。 ### 回答2: React-Saga和React-Thunk都是React应用中用于处理异步操作的中间件。它们的主要目的是在Redux应用中,帮助我们管理异步操作。这两个中间件都可以让React应用更加的灵活、健壮和易于维护。 React-Saga的核心理念是利用生成器函数来处理异步操作,Saga通过使用生成器来让异步操作变得像同步操作一样,其中每个异步操作都会被转化为一个迭代器函数,这些函数可以被Saga调用和暂停。 Saga主要有以下几个特点: 1. Saga可以使异步操作更加同步和简单,让异步调用变得更容易。Saga使用了轻量级、高效的生成器函数,从而有效地减少了异步调用中的代码复杂度。 2. Saga可以很好地管理和协调多个异步操作。Saga可以在任意阶段暂停异步操作,等待其他异步操作完成之后再继续执行。 3. Saga可以捕获和控制异步操作的错误、超时和状态。当出现问题时,Saga可以修复错误或者更改异步操作的状态,保证应用程序的稳定性和可靠性。 React-Thunk的核心概念是利用闭包函数来处理异步操作,Thunk将异步操作转化为一个闭包函数,然后通过回调函数将其传递到Redux的异步流中。 Thunk的主要特点有以下几个: 1. Thunk可以轻松处理异步操作,没有复杂的代码逻辑或者概念。 2. Thunk主要使用了闭包函数来捕捉当前异步操作的上下文,使得处理异步操作更加的简单、方便和自然。 3. Thunk可以轻松控制异步操作的状态、结果和错误处理,保证应用程序的稳定性和可靠性。 总之,React-Saga和React-Thunk都是帮助我们管理和处理应用程序的异步操作的中间件。它们都有自己独特的实现方式和特点。我们可以根据自己的项目需求和开发团队的技能水平来选择适合我们的中间件。 ### 回答3: React-saga 和 React-thunk 都是针对 React 应用中异步操作的中间件。它们两个都可以用来控制异步流程,使得我们可以更好的管理 React 应用程序中异步操作的数据和状态。 相较于 react-thunk, react-saga 是一个更加强大的中间件,它基于 generator 函数的概念,可以用来控制非常复杂的异步流程,使得我们可以在操作时更加精细地掌控多个异步操作的执行顺序和状态。 如果说 react-thunk 的核心概念是将异步操作封装进一个函数里,而在需要时调用这个函数即可,那么 redux-saga 的核心概念则是分离出一个独立的 Generator 函数来代表所有的异步业务逻辑。 redux-saga 可以让你从另一个角度处理异步流程,使你能够同步处理异步操作,不同的 Saga 可以用一种集中且易于理解的方式组合起来,组成它们自己的执行序列。 总而言之,React-saga和React-thunk 都是 React 应用程序开发中非常实用的工具,对于管理异步操作和数据状态非常有帮助。但是针对不同的开发需求,我们需要选择相应的中间件,来实现我们最好的业务逻辑。所以我们在使用的时候需要根据实际情况选择适合的中间件进行操作,以达到最好的效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值