React5—— Redux React-redux Redux-thunk

这篇从redux讲起,redux不经常单独使用,而是与react-redux这个绑定库一起完成大量操作,使代码结构更加清晰,最后简单讲解redux-thunk,它是实现异步请求的常用中间件之一。掌握这三个知识点后,就可以实现一个完整react的Demo啦~(redux-saga较复杂,单独放在下次)

Redux

Redux 是 JavaScript 状态容器,提供可预测化的状态管理。
Redux 除了和 React 一起用外,还支持其它界面库。

Store

数据仓库,使用createStore函数,用来生成 Store

import { createStore } from 'redux';
const store = createStore(fn);// fn是一个函数
  • 创建仓库store后,在组件内可以使用方法store.subscribe,store.dispatch,store.getState,store.subscribe
  • State: 是Store对象包含的全部数据,如上所述,当前时刻的数据可以用store.getState获取
  • 获取数据
    let state = store.getState()
  • 修改数据
    store.dispatch({type: "add", content: { msg: '一些数据 '}})
  • 监听视图
  //监听数据变化,重新渲染页面
store.subscribe(() => {
  ReactDOM.render(<Timer></Timer>, document.getElementById('root'))
    })
Action

是一个对象,必须有type属性,其余属性皆可自定义,它是 store 数据的唯一来源

const action = {
  type: 'ADD_TODO',
  text: 'Learn Redux'
};
Action Creator

是生成 action 的方法,可以看出这个函数只是返回了一个简单的action

function addTodo(text) {
  return {
    type: ADD_TODO,
    text
  }
}
Dispatch

store.dispatch接受一个 Action 对象作为参数,将它发送出去

store.dispatch({type: "add", content: { msg: '一些数据 '}})
// 或者调用Action Creator
store.dispatch(addTodo('Learn Redux'));
Reducer

一个函数 通过获取动作改变数据,生成一个新的state,从而改变页面 ( reducer会接收到action的信息 并进行state处理),combineReducers可以把多个reducer函数合并

import * as types from './actionType'
// 可以描述一个初始state
const initState = {
  ...
}
const reducer = function(state = initState, action) {
  switch(action.type) {
      // 根据不同的action.type
      // type一般大写定义
  case types.SET_BUTTON_LOADING: {
        let newState = JSON.parse(JSON.stringify(state))
        newState.submitdDisabled = action.buttonLoading;
    // 生成新的state
        return newState
      }
    case types.CHANGE_TASK_SWITCH: {
      let newState = JSON.parse(JSON.stringify(state))
      newState.taskSwitch = action.taskSwitch;
      return newState;
    }
    default:
      return state
  }
Redux流程图

在这里插入图片描述

react-redux

  • Redux 官方提供的 React 绑定库。 具有高效且灵活的特性
  • 使用redux时,我们需要进行大量的手工订阅state的状态变化,再进行对state的修改,在使用react-reudx这个工具后,我们只需对store进行处理,react组件就会有相应的变化
  • react-redux的思路是 把store直接集成到React应用的顶层props里面,这样各个子组件就能访问到顶层props了
  • 它有两个API :<Provider store> connect([mapStateToProps], [mapDispatchToProps], [mergeProps], [options])
<Provider store>
  • Provider目的是使所有组件都能访问到redux中的数据 (把store和组件中的state进行关联)
  • Provider相当于一个顶级组件,将自己的根组件嵌在它之中才能使用connect方法,否则要把 store 作为 props 传递到每一个被 connect() 包装的组件才行
import { Provider } from 'react-redux'
import store from './store'
ReactDOM.render(
  <Provider store={store}>
    <MyRootComponent />
  </Provider>,
  root
)
connect([mapStateToProps], [mapDispatchToProps], [mergeProps], [options])

connect是用来连接 React 组件与 Redux store(它将store上的getState 和 dispatch 包装成组件的prop)

mapStateToProps(state, [ownProps]): stateProps
  • mapStateToProps是把state映射到props中去 ,这个函数有两个参数,第一个参数如果写了会监听Redux store的变化

  • 如果指定了该回调函数中的第二个参数 ownProps,则该参数的值为传递到组件的 props,而且只要组件接收到新的 props,mapStateToProps 也会被调用(例如,当 props 接收到来自父组件一个小小的改动,那么你所使用的 ownProps 参数,mapStateToProps 都会被重新计算)。

mapDispatchToProps(dispatch, [ownProps]): dispatchProps
  • mapDispatchToProp把各种dispatch也变成了props让你可以直接使用(实现了方法的共享)
// 在组件中使用时
// mapStateToProps是把state映射到props中去
// mapDispatchToProp把各种dispatch也变成了props让你可以直接使用


const mapStateToProps = (state) => { 
// 必须返回一个纯对象
    return { // prop : state.xxx | 意思是将state中的某个数据映射到props中 
                foo: state.bar 
        } 
    }  // 渲染的时候就可以使用this.props.foo


const mapDispatchToProps = (dispatch) => { 
    // 默认传递参数就是dispatch 
    return { onClick: () => { dispatch({ type: 'increatment' }); 
        } 
    }; 
}
// 然后render中直接通过this.props.onClick来调用dispatch,这样子就不需要在代码中来进行store.dispatch了
connect(mapStateToProps, mapDispatchToProps)(MyComponent)

React-redux流程图

在这里插入图片描述

Redux-thunk

redux-thunk 是一个比较流行的 redux 异步 action 中间件

使用方法:

store->index.js:

import { createStore, applyMiddleware } from 'redux' // 引入 createStore方法
import thunk from 'redux-thunk'; // 引入redux-thunk
import reducer from './reducer' // 引入reducer
const store = createStore(reducer, applyMiddleware(thunk)) // 创建数据存储仓库

export default store // 将仓库暴露出去

组件内使用mapDispatchToProps dispatch方法与之前相同,reducer的写法也相同

store->actionCreate.js中生成action时:

  1. 首先这个函数使用dispatch作为参数(这解决了dispatch 不好获取的问题);当redux-thunk发现组件内dispatch了一个函数,它就会传递一个dispatch 参数,而不会传递给 reducer,防止reducer 遇到一个函数而不知所措。
  2. 函数内可以使用一些异步方法,比如axios或者fetch,处理完之后触发一个 dispatch,使它返回一个简单的同步action即可。

如下例:

const getId = (user_group_id) => {
  return (dispatch) => {
    axios.get('.../detail', {
        params: {
          user_group_id
        }
      })
      .then((response) => {
          const data = response.data.result_data.group_info
          // console.log(data)
          dispatch(getDetail(data))
        
      })
      .catch(() => {
          console.log('catch')
      })
    }
}

function getDetail (data) {
    return {
      type: GET_DETAIL,
      data
    }
  };
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值