Redux概述

react-redux

1. Redux概述

1.1 什么是Redux

  • Redux 是一个用于JavaScript状态容器,提供可与预测化的状态管理
  • Redux 可以让你构建一致化的应用,运行于不同的环境(客户端、服务器、原生应用),并且易于测试
  • Redux 除了和React一起使用外,还支持其他界面库,而且它体小精悍(只要2kB)

在这里插入图片描述

1.2 Redux 三大核心

  1. 单一数据源

整个应用的state被存储在一颗 0bject tree 中,并且这个 0bject tree 只存在于唯一一个 store 中

  1. State 是只读的

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

这样确保了视图和网络请求都不能直接去修改state,相反,它们只能表达想要修改的意图,因为所有的修改都被集中化处理,并且严格按照一个接一个的顺序执行

store.dispatch({type: 'COMPLETE_TODO',index: 1})
  1. 使用纯函数来执行修改
纯函数的含义:指没有副作用不依赖外部变量,同样的输入产生同样的输出,也是幂等的

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

Reducers 只是一些纯函数,它接收先前 的 state 和action ,并且返回新的 state,

可以复用,可以控制顺序、传入附加参数

2. Redux 组成

2.1 State 状态

就是我们传递的数据,那么我们在用React 开发项目的时候,大致可以将state 分为三类:

  • DomainDate:可以理解成为服务器端的数据,比如:获取用户的信息,商品的列表等等
  • UI State:决定当前UI 决定展示的状态,比如:弹框的显示隐藏、受控组件等等
  • App State:App 级别的状态,比如:当前是否请求loading效果,当前路由信息等可能被多个和组件去使用的到的状态

2.2 Action 事件

Action 是把数据从应用(也就是组件)传到store的载体,它是store数据的唯一来源,一般来说,我们可以通过store.dispatch( ) 将 action 传递给 store

Action 特点:

  • Action 的本质就是一个 JavaScript 的普通对象

  • Action 对象内部必须要有一个 type 属性来表示要执行的动作(发送多个action,用type进行区分)

  • 多数情况下,这个 type 会被定义成字符串常量

  • 除了 type 字段之外,action 的结构随意进行定义

而我们在项目中,更多的喜欢用 action 创建函数(就是创建 action 的地方)

action 创建函数,返回一个 action 对象

function addAction(params) {
	return {
		type: 'add',
		...params
	}
}
只是描述了有事情要发生,并没有描述如何去更新 state

2.3 Reducer

Reducer 本质是一个函数,它用来响应发送过来的actions,然后经过处理,把state 发送给 store 的

注意:在 Reducer 函数中,需要 return 返回值,这样 store 才能接收到数据

函数会接收两个参数,第一个参数是初始化 state,第二个参数是 action

2.4 Store

Store 就是把 action 与 reducer 联系到一起的对象

通过 createStore 来构建 store

通过 subscribe 来注册监听

通过 dispatch() 方法发送 action

import { createStore } from "redux";
const store = createStore(传递reducer);

主要职责:

  • 维持应用的 state
  • 提供 getState() 方法获取 state
  • 提供 dispatch() 方法发送 action
  • 通过 subscribe() 来注册监听
  • 通过 subscribe() 返回值来注销监听

3. Redux 入门案例

3.1 准备工作

  • Redux_Dev_Tools的安装(在谷歌应用商店,搜索:redux dev)

将下面代码复制粘贴到 store / index.js

// 构建 store
const store = createStore(
 reducer,
 window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
);
  • 构建 react 项目
npx create-react-app redux-demo
  • 删除多余的文件只保留 src目录下的这些文件
App.js
import React from 'react';

import Home from "./pages/home";

function App() {
return (
<div className="App">
  <Home />
</div>
);
}

export default App;

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

ReactDOM.render(
<App />,
document.getElementById('root')
);
idnex.css
  • src / 在 pages 目录下 创建 Home 组件 / 创建 index.js
import React from 'react'


export default class Home extends React.Component {
render() {
return (
<button>发送一个action</button>
)
}
}


  • 编写一个简单的结构样式
<button>发送一个action</button>
  • 在App.js 中引入这个组件
import Home from "./pages/home";
  • 安装 redux
yarn add redux

npm i redux

cd 项目根目录,yarn start 运行项目

3.2 创建一个 Action

src / 创建一个文件夹 action / 创建一个 index.js文件,用来 构建 Action

  • 在 action 创建函数里面 利用 return,返回一个 action 对象,注意需要携带 type 属性
  • 把这个action创建函数进行导出
src / action / index.js
const sendAction = () => {
return {
  type: "send_action",
  value: "发送了一个action"
}
}

module.exports = { sendAction }

3.3 创建一个 Reducer

src / 创建文件夹 reducer / 创建 index.js 文件,用来构建 reducer ,注意 reducer 要接收两个参数

  • 第一个参数是默认状态,我们可以定义一个初始化的 state ,然后进行赋值
  • 在函数里面判断第二个参数 action 的type值是否是我们发送的

如果是的话,我们可以通过 return 返回新的 state

然后把 reducer 进行导出

src / reducer / index.js 文件
const initState = {
value: '默认值'
};

const reducer = (state = initState, action) => {

console.log(reducer, state, action)

switch (action.type) {
  case 'send_action':
      return Object.assign({}, state, action);
  default:
      return state;
}
};

module.exports = {
reducer
};

3.4 创建 Store

createStore的第三个参数的定义

(1)官方定义:createStore(reducer, [initialState], enhancer)

​ 第三个参数enhancer, 是一个组合 store creator 的高阶函数,返回一个

​ 新的强化过的 store creator。这与 middleware 相似,它也允许你通过

​ 复合函数改变 store 接口。

src / 创建一个文件夹 store / index.js 文件,用来 构建 store,

注意:

  • createStore 函数里面第一个参数接收的是 reducer
  • 我们需要导入刚刚创建的 reducer,然后设置到函数里面去
  • createStore 的返回值就是我们构建好的 store,然后进行导出
src / store / index.js 文件
import { createStore } from 'redux';

// 导入我们自己创建好的 reducer
import { reducer } from '../reducer';

// 构建 store
const store = createStore(reducer);

export default store;

3.5 在Home组件开始使用

  • 导入 store 和 action 构造函数
  • 在页面的button按钮绑定一个点击事件
  • 在组件一加载完毕的时候我们通过 store 来进行监听器的注册,返回值可以用来注销监听
  • 在点击事件处理函数中,通过 store.dispatch() 来发送一个 action
src / home / index.js 文件
import React from 'react'

// 导入 store
import store from '../../store';

// 导入 action 构造函数
import { sendAction } from '../../action';

export default class Home extends React.Component {

handleClick = () => {
const action = sendAction();
// 发送一个 action
store.dispatch(action);
}

// 当组件一加载完毕的时候 来监听
componentDidMount() {
 store.subscribe(() => {
     console.log(store.getState())
     this.setState({})
 })
}

render() {
	return (
     <>
       <button onClick={this.handleClick()}>发送一个action</button>
       <div>{store.getState().value}</div>
     </>
 )
}
}

3.6 Redux 入门案例小结

  1. 构建 action,通过创建一个函数,然后返回一个对象,注意需要携带 type 属性
  2. 构建 reducer ,用来响应 action,然后通过 return 把数据传回 给 store
  3. 利用 createStore 来构建 store,构建的时候传递我们写好的 reducer
  4. 利用 store.subscribe() 注册监听
  5. 当我们利用 store.dispatch() 发送一个 action 的时候就能触发我们的监听了,在里面利用 store.getState() 就能拿到值

4. React-redux 概述

4.1 Redux 与 React 的关系

Redux 与 React 之间是没有关系的,Redux 支持 React、Angular、jQuery 甚至是JavaScript

Redux 与 React 这类库搭配起来更好用

4.2 React-redux

react-redux 就是 Redux 官方出的 用于配合 React 的绑定库

react-redux 能够使你的 React 组件从 Redux store 中很方便的读取数据,并且向 store 中分发 actions

以此来更新数据

两个重要的成员:

在学习React 的时候,我们了解到,React 这个UI的框架是以 组件来进行驱动的,所以 react-redux 中

有两个重要的部分,先来认识一下吧!

  • Provider:这个组件能够使你整个app都能获取到 store 中的数据

    Provider 包裹 在根组件最外层,使所有的子组件都可以拿到 state

    Provider 接收 store 作为 props,然后通过 context 往下传递,这样 react 中任何组件都可以通过

    context 获取到 store

    react-redux Provider内容介绍
    解决了麻烦容器组件可能存在很深的层级,防止了一层一层去传递 state
    作用让组件 拿到 state
    原理react 中 的 context
  • connect:这个方法能够使组件跟 store 来进行关联

    Provider 内部组件如果想要使用到 state 中的数据,就必须要 connect 进行一层包裹封装,换一句话来说就是必须要被 connect 进行加强

    connect 就是方便我们组件能够获取到 store 中的 stae

4.3 React-redux 基本使用

4.3.1 安装 react-redux

react-redux 不是 react 官方所提供,所以当我们构建 react 项目之后,需要进行安装

react-redux 还需要依赖与Redux中的 store,所以我们还需要安装 redux

yarn add react-redux
yarn add redux

npm install react-redux
npm install redux
4.3.2 利用 redux 来构建 store
  • 创建 reducer / index.js 文件,构建 reducer 来响应 actions
exports.reducer = (state,action)=>{
	return state;
}
  • 创建 store/ index.js 文件,通过 createStore 方法,把我们的 reducer 传入进来
import { createStore } from 'redux';
import { reducer } from '../reducer';
export default createStore(reducer);
  • 在 App.js 中引入 store
import store from './store';
4.3.3 搭建页面结构
  1. src / pages / 创建一个组件ComA / index.js,里面放一个 button 按钮
import React from 'react'

export default class ComA extends React.Component {
 render(){
     return (
         <button> + </button>
     )
 }
}
  1. src / pages / 创建另一个组件ComB / index.js,里面放一个 div,用来显示数字
import React from 'react'

export default class ComB extends React.Component {
 render(){
     return <div>1</div>
 }
}
  1. 在 App.js 中引入两个组件
import ComA from "./pages/ComA";
import ComB from "./pages/ComB";

4.3.4 引入 Provider 组件
  • 在 App.js 中导入 Provider 组件
import { Provider } from 'react-redux'
  • 利用 Provider 组件将我们整个结构进行包裹,并且传递 store,从而能够达到统一维护 store 的效果
function App() {
	return (
		<Provider store={store}>...</Provider>
	)
}
  • 只要我们把 store 传递给了 Provider 组件,那么 Provider 组件就会在内部帮我们维护好 store
4.3.5 connect 使用
  • 导入 connect 方法
import { connect } from 'react-redux';
  • 调用 connect 方法

connect-参数说明

参数名类型说明
mapStateToProps(state,ownProps)Function这个函数允许我们将 store 中的数据作为 props 绑定到组件上
state:redux中的store
ownProps:自己的props
mapDispatchToProps(dispatch,ownProps)Function将action作为props绑定到我们自己的函数中
dispatch:就是store.dispatch();<br /ownProps:自己的props>
mergeProps(stateProps,dispatchProps,ownProps)Function不管是 stateProps 还是 dispatchProps ,都需要和ownProps merge 之后才会被赋给我们的组件。
通常情况下,你可以不传这个参数,connect 就会使用 Object.assign替代该方法
optionsObject可以定制 connector 的行为
connect(...)(Component)
  • connect 方法会有一个返回值,而这个返回值就是加强之后的组件
4.3.6 利用 connect 方法让我们组件 与 store 关联
  • 在组件ComA 和 ComB,分别导入 connect 方法
import { connect } from 'react-redux'
  • 利用 connect 方法来对我们组件进行改造,并且导出
export default connect(mapStateToProps,mapDispatchToProps)(Home)
  • 组件 ComA / index.js 属于 发送方,所以要实现第二个参数

    ComA 发送 action ;导入 connect

    利用 connect 对组件进行加强:connect (要接收数据的函数,要发送action的函数)(放入要加强的组件)

    我们需要实现 connect 的第二个参数

    构建一个函数 mapDispatchToProps (dispatch);dispatch就是用来发送给action的

    在这个函数里面就可以返回一个对象:key:是方法名;value:调用dispatch 去发送 action

    在组件的内容 就可以通过 this.props 来拿到这个方法了

import React from 'react'

import { connect } from 'react-redux'

class ComA extends React.Component {

handleClickItem = ()=>{
  console.log('ComA',this.props)
  // 发送 action
  this.props.sendAction();
}
render() {
  return <button onClick={this.handleClickItem}> + </button>
}
}

/**
 * 这个函数要有一个返回值,返回值是一个对象
 * @param{} dispatch
*/
const mapDispatchToProps = (dispatch) => {
return {
  sendAction: () => {
      // 利用 dispatch 发送一个 action
      // 传递 action 对象,我们要定义type属性
      dispatch({
          type: 'add_action'
      })
  }
}
}

//  A 是 发送方,所以要实现第二个参数,不需要接收参数定义 null
//  mapDispatchToProps 这个函数要有一个返回值,返回值是一个对象,这个对象会当做props属性传递回组件ComA
export default connect(null, mapDispatchToProps)(ComA)
  • 组件 ComB 属于 接收方,所以要实现 connect 方法的第一个参数

    ComB 接受 state

    1. 导入 connect 方法

    2. 利用 connect 对组件进行加强

    3. 组件 ComB 属于 接收方,所以要实现 connect 方法的第一个参数

    mapStateToProps 里面的一个参数就是我们很关心的 state

    把这个 state 进行 return 才能在组件的内部获取到 最新的数据

    ComB 是否能拿到数据,关键点 是 reducer reducer返回什么,ComB 就拿到什么

    只有 reducer 里面返回了新的state的时候,组件 ComB才能够获取到 新的state

    然后 通过 mapStateToProps 函数 把这个 state 进行 return

    才能在组件 ComB 的内部获取到 最新的数据 this.props.属性

import React from 'react'

import { connect } from 'react-redux'

class ComB extends React.Component {
render(){
  console.log('ComB',this.props)
return <div>{this.props.count}</div>
}
}

const mapStateToProps = (state)=>{
console.log('ComB',state)
return state
}

// 组件 ComB 属于 接收方,所以要实现connect 方法的第一个参数
export default connect(mapStateToProps)(ComB);
4.3.6 关系图

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

落花流雨

你的鼓励将是我创作的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值