react、react-redux、redux-thunk、react-saga运用

作者: tww844475003 分类: 前端开发 发布时间: 2021-06-28 22:45

动机

随着 JavaScript 单页应用开发日趋复杂,JavaScript 需要管理比任何时候都要多的 state (状态)。 这些 state 可能包括服务器响应、缓存数据、本地生成尚未持久化到服务器的数据,也包括 UI 状态,如激活的路由,被选中的标签,是否显示加载动效或者分页器等等。

三大原则

  • 单一数据源

整个应用的 state 被储存在一棵 object tree 中,并且这个 object tree 只存在于唯一一个 store 中。

  • State 是只读的

唯一改变 state 的方法就是触发 action,action 是一个用于描述已发生事件的普通对象。

  • 使用纯函数来执行修改

为了描述 action 如何改变 state tree ,你需要编写 reducers

运用

下面,笔都运用一个简单的增加、减少的列子来解读 react-redux 神奇之处。

首先 react-cli 安装一个项目,这块步骤,网上很多教程,就不再继续累赘了。

  • 安装 redux 状态管理所需要的模块
npm i -D react-redux redux-thunk

这里解释一下,其实不涉及异步的的 state 状态,不需要 redux-thunk 中间件,这里我们选择带上,是因为一个应用项目肯定会涉及到异步请求。下面来跟着一步步的改造 脚手架生成的项目。(代码编辑器里加粗的是我们要改造的代码块)

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import 'antd/dist/antd.css'; // or 'antd/dist/antd.less'
import { Provider } from 'react-redux';
import Store from './store/index'

const store = Store();

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

store/index.js

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

const store = () => createStore(reducer, applyMiddleware(thunk));

export default store;

reducer.js

const initialState = { count: 0 };
const reducer = (state = initialState, action) => {
  switch (action.type) {
    case 'ADD_CONST':
      return { count: state.count + 1 };
    case 'MINUS_CONST':
      return { count: state.count - 1 };
    default:
      return state;  
  }
}

export default reducer;

actions.js

export const addConst = () => {
  return {
    type: 'ADD_CONST'
  }
}

export const minusConst = () => {
  return {
    type: 'MINUS_CONST'
  }
}

CustomCount.js 组件

bindActionCreators 是 redux 的一个 API,作用是将单个或多个 ActionCreator 转化为 dispatch(action) 的函数集合形式。也可以不用 bindActionCreators,dispatch 也是可以的

react-redux的connect方法 接受4个参数

  1. mapStateToProps(state, [ownProps]) 接受完整的redux状态树作为参数,返回对象的所有key都会成为组件的props
  2. mapDispatchToProps(dispatch, [ownProps]) 接受redux的dispatch方法作为参数,返回当前组件相关部分的action creator并可以在这里将action creator与props绑定,减少冗余
  3. mergeProps(stateProps, dispatchProps, ownProps) 如果指定这个函数,你将分别获得 mapStateToProps、 mapDispatchToProps 返回值以及当前组件的props 作为参数,最终返回你期望的、完整的 props
  4. [options] : pure:true, 将为组件添加shouldComponentUpdate()声明周期函数;
  5. withRef:false, 若为true,为组件加一个ref值,后续可以使用 getWrappedInstance() 方法来获取该 ref
import React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import * as countActions from '../store/action';

class CustomCount extends React.Component {
  render() {
    const { count, actions } = this.props;

    return (
      <div>
        <span>{count}</span>
        <button onClick={actions.addConst}>+</button>
        <button onClick={actions.minusConst}>-</button>
      </div>
    )
  }
}

const mapStateToProps = (state) => {
  return {
    count: state.count
  }
}

const mapDispatchToProps = (dispatch) => {
  return {
    actions: bindActionCreators(countActions, dispatch)
    // actions: {
    //   addConst: () => dispatch(countActions.addConst()),
    //   minusConst: () => dispatch(countActions.minusConst())
    // }
  }
}

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(CustomCount);

react-saga

请移步:https://www.ifrontend.net/2021/07/redux-saga/

前端开发那点事
微信公众号搜索“前端开发那点事”

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注