redux、react-redux一篇掌握

简介: redux、react-redux一篇掌握

目录

前言



介绍了redux的几个核心概念,循序渐进,掌握redux的概念之后,再接入react-redux,主流使用方法,以例子的形式介绍,如果耐心阅读下来,相信你可以完全掌握。


redux几个概念


reducer


说是reducer,其实就是一个函数,入参state(状态)与action(动作)。

action是个对象,里面的type属性区分动作类型,根据动作类型修改状态state后,返回新的状态state。

里面也不一定那么死板必须是switch,用if else也可以达到同样的效果

function counter(state = 0, action) {
  switch (action.type) {
    case 'add':
      return state + 1;
    case 'del':
      return state - 1;
    default:
      return state;
  }
}

store


reducer只是一个函数而已,为什么与redux有关系?因为这个函数形式是由redux决定的,它作为创造store的入参。

createStore是redux用于创造store的函数,入参就是reducer函数。

store有几个方法,dispatch、subscribe、getState等。

dispatch:入参就是对应reducer的action对象,中间可以自己传递动作类型type的值,触发action就是用于修改状态的唯一方法,action中也可以自定义额外传递其他的任何属性,比如修改state需要用的数据。

subscribe:订阅,当dispatch触发时就会调用,订阅之后可以用于自己额外做一些事情,比如手动渲染。且它的返回值就是它的注销函数。

getState:获取状态。

import { createStore } from 'redux';
...//上面reducer代码
const store = createStore(counter);
store.dispatch({ type: 'add' });
const unSubscribe = store.subscribe(() => {
  console.log(store.getState());
});
//注销监听
unSubscribe()

reducers

  1. 一般一个我们尽量保持一个state,但是state可能中间存在多个数据,且需要的动作不一致,因此我们会创造很多个reducer,然后合并成一个。
  2. 短暂思考一下,不难理解,以下代码,all这个reducer借助不同的reducer合并在一起,并且只保持一个状态。
function num(state = 0, action) {
  switch (action.type) {
       ...
  }
}
function obj(state = {}, action) {
  switch (action.type) {
       ...
  }
}
function all(state = {}, action) {
  return {
     obj: obj(state.obj, action),
     num: num(state.num, action),
  }
}
  1. all可以通过combineReducers方法实现,不用手写。
import { combineReducers } from 'redux'
let all = combineReducers({ num, obj })

action

  1. action就是reducer的第二个入参,一般action中我们都会用一个字符串定义type属性,当内容越来越多时,我们也许会使用单独文件定义type常量。
const ADD = 'add'
export default { ADD }


import { ADD } from '../actionTypes'
const action = { type: ADD }
...
store.dispatch(action)
  1. action创建函数,如果action需要额外的属性值用于修改状态,可以声明为函数,也比较方便,
const action = num => {
  return {
    type: 'add',
    num,
  };
};
store.dispatch(action(1));
  1. 还可以创建函数,自动dispatch。(后面介绍mapDispatchToProps时就是用的这个方法,先理解)
const action = num => {
  return {
    type: 'add',
    num,
  };
};
//被绑定的action创建函数,自动dispatch
const boundAction = num => {
  store.dispatch(action(num))
};
boundAction(1)

react-redux使用


首先你可以明确,react-redux是让redux支持react且完成了一定性能优化的库,你不想也可以就掌握redux,并用订阅subscribe去更新组件,当然这也没必要,因为react-redux中的connect方法很好用。


创建reducers


./reducers/count/index.js

const counter = (state = 0, action) => {
  switch (action.type) {
    case 'add':
      return state + action.num;
    case 'del':
      return state - action.num;
    default:
      return state;
  }
};
export default counter;

./reducers/other/index.js

const other = (state = 0, action) => {
  switch (action.type) {
   ...
  }
};
export default other;

创建多个reducer之后,整合在reducers的index.js中

./reducers/index.js

import count from './count';
import other from './other';
...
import { combineReducers } from 'redux';
const reducers = combineReducers({ count, other });
export default reducers;

在入口创建store


react-redux中的Provider用的是react中contexts的原理,让被它包裹的组件都可以用connect方法关联store。


引入创建的所有reducer生成store,在入口包裹一层Provider,并传递store。


当然也不一定要是在入口,放在你想要控制需要同一状态的许多组件的共同父级即可。

import React from 'react'
import { render } from 'react-dom'
import { Provider } from 'react-redux'
import { createStore } from 'redux'
import reducers from './reducers'
import App from './components/App'
let store = createStore(reducers)
render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
)

创建actions

只需要index.js文件就够了,将所有reducer中涉及到的动作都创建对应的action创建函数。一个reducer可能需要多个action函数,比如counter就需要2个。

./actions/index.js

function add(num) {
  return {
    type: 'add',
    num,
  };
}
function del(num) {
  return {
    type: 'del',
    num,
  };
}
...
export default { add, del, ... };

创建containers容器


我们用redux的目的是为了让我们的组件可以获得全局可控的某状态,容器就是状态的承载物。


我们将需要用store中状态的组件就可以包裹上容器,容器包裹组件需要用到connnect方法。


connect是一个高阶函数,首先它有两个入参,mapStateToProps,mapDispatchToProps,一个个来。


mapStateToProps:需要让普通组件获得的状态值,入参的state就是store的state,也就是我们reducers创建的store的state,不知道有啥就去我们的在reducers文件夹中去找,比如我们的count,other等等。

mapDispatchToProps:需要让普通组件控制修改store的state的方法,入参的dispatch,同理是store的diapatch,我们利用前面写好的actions在里面声明自动dispatch方法,不知道有哪些方法同理我们去actions文件夹找,会看到对应的方法。

最后用connect(mapStateToProps,mapDispatchToProps)这个函数返回的还是一个函数,入参放入我们的普通组件,这里我简单命名为TestComponent。

后续如果其他需要使用TestComponent组件的父级组件,不再引入TestComponent,都去引入当前的TestComponent的容器组件,容器组件就是将mapStateToProps和mapDispatchToProps中的属性和方法都传递给了TestComponent的props,TestComponent组件内容仍然没变。

./Containers/TestComponentContainer/index.js

import TestComponent from '../../components/TestComponent';
import actions from '../../actions';
import { connect } from 'react-redux';
const mapStateToProps = state => {
  return {
    count: state.count,
    ...
  };
};
const mapDispatchToProps = dispatch => {
  return {
    addNum: num => {
      dispatch(actions.add(num));
    },
    delNum: num => {
      dispatch(actions.del(num));
    },
  };
};
export default connect(mapStateToProps, mapDispatchToProps)(TestComponent);

普通组件components

值和回调函数都从props获取,实现简单的控制数字加减。

./components/TestComponent/index.js

import React, { Component } from 'react';
export default class index extends Component {
  render() {
    const { count, addNum, delNum } = this.props;
    return (
      <div>
        <div>{count}</div>
        <button
          onClick={() => {
            addNum(1);
          }}
        >
          点击加1
        </button>
        <button
          onClick={() => {
            delNum(1);
          }}
        >
          点击减1
        </button>
      </div>
    );
  }
}
相关文章
|
4月前
|
前端开发 JavaScript 测试技术
从零开始搭建react+typescript+antd+redux+less+vw自适应项目
从零开始搭建react+typescript+antd+redux+less+vw自适应项目
135 0
|
30天前
|
存储 JavaScript 前端开发
React中使用redux
React中使用redux
127 56
|
23天前
|
存储 JavaScript 前端开发
react redux 实现原理
【8月更文挑战第29天】react redux 实现原理
17 4
|
20天前
|
前端开发 Java UED
瞬间变身高手!JSF 与 Ajax 强强联手,打造极致用户体验的富客户端应用,让你的应用焕然一新!
【8月更文挑战第31天】JavaServer Faces (JSF) 是 Java EE 标准的一部分,常用于构建企业级 Web 应用。传统 JSF 应用采用全页面刷新方式,可能影响用户体验。通过集成 Ajax 技术,可以显著提升应用的响应速度和交互性。本文详细介绍如何在 JSF 应用中使用 Ajax 构建富客户端应用,并通过具体示例展示 Ajax 在 JSF 中的应用。首先,确保安装 JDK 和支持 Java EE 的应用服务器(如 Apache Tomcat 或 WildFly)。
27 0
|
20天前
|
存储 JavaScript 前端开发
探索React状态管理:Redux的严格与功能、MobX的简洁与直观、Context API的原生与易用——详细对比及应用案例分析
【8月更文挑战第31天】在React开发中,状态管理对于构建大型应用至关重要。本文将探讨三种主流状态管理方案:Redux、MobX和Context API。Redux采用单一存储模型,提供预测性状态更新;MobX利用装饰器语法,使状态修改更直观;Context API则允许跨组件状态共享,无需第三方库。每种方案各具特色,适用于不同场景,选择合适的工具能让React应用更加高效有序。
32 0
|
1月前
|
存储 JavaScript 前端开发
"探索Redux的Vuex化:如何在React世界中享受Vue状态管理的优雅与强大"
【8月更文挑战第21天】在现代前端开发中,状态管理至关重要。Vuex作为Vue.js的状态管理库,通过集中式存储和严格规则确保状态变更的追踪。Redux则以其在React生态中的可预测性和灵活性著称。两者都强调单一数据源、状态只读及使用纯函数变更状态。尽管API设计不同,理解Redux的核心概念——单一数据源(`store`)、状态只读与纯函数变更(`reducers`),并参考Vuex的`state`、`mutations`等,能帮助开发者快速掌握Redux,高效管理应用状态。
15 0
|
1月前
|
JavaScript 前端开发 安全
|
2月前
|
Web App开发 JavaScript 前端开发
react18【系列实用教程】搭建开发环境(2024版)Vite+React (官方推荐)(含@配置,react-developer-tools 和 Redux DevTools 下载安装)
react18【系列实用教程】搭建开发环境(2024版)Vite+React (官方推荐)(含@配置,react-developer-tools 和 Redux DevTools 下载安装)
182 0
|
4月前
|
存储 JavaScript 前端开发
基于React和Redux的待办事项列表应用
基于React和Redux的待办事项列表应用
52 0
|
4月前
|
JavaScript 前端开发 搜索推荐
构建一个基于React和Redux的简易电商购物车应用
构建一个基于React和Redux的简易电商购物车应用
53 0

热门文章

最新文章