React-redux
React-Redux
我们先复习一下 Redux,如果说我们想要发送一个action给store,那么我们得先导入store 然后执行store.dispatch(action)
来发送action。这个 action 就会被发送到我们定义的 reducer 纯函数里面去,而在 reducer 中通过 return 会把新数据返回到 store 里面去。
而在我们的组件内部,如果想要接收到我们最新的 state状态 ,那么在组件内部我们也要导入store,通过store.subscribe(()=>{//回调函数})
注册监听,才能拿到数据store.getState()
。
这时候我们会发现,无论发送action还是接收新数据,都得导入store,非常麻烦。那么这时候就出现了一个角色:React-redux。
1.React-redux概述
1.1 Redux 与 React 的关系
其实他们之间是没有关系的,哈哈哈哈哈哈。只不过Redux与React这类库搭配起来更好用。
1.2 React-redux
而react-redux就是 Redux官方出的 用于配合React的绑定库
react-redux 能够使你的React组件从Redux store中很方便地读取数据,并且向store中分发actions以此来更新数据
1.3 React-Redux中两个重要的成员
在学习React的时候,我们了解到,React这个UI的框架使以组件来进行驱动的,所以react-redux中有两个重要部分要先认识一下:
Provider:这是一个组件。这个组件能够 让我们整个app都能获取到store中的数据。
connect: 这是一个方法。这个方法能够 让组件跟store进行管理
1.4 Provider
- Provider包裹在 根组件的最外层,使得所有子组件都能够拿到State
- Provider接收 store 作为 props,然后通过context往下传递,这样react中任何组件都可以通过context获取到store
1.5 connect
- Provider内部组件如果想要使用到 state 中的数据,就必须要 connect 进行一层包裹封装。
- connect 就是方便我们组件能够获取到 store 中的 state
2.React-redux 基本使用
2.1 安装插件 react-redux
首先像上一篇文章的“入门案例”处一样创建一个react项目 juejin.cn/post/715787…
react-redux不是react官方所提供,所以当我们构建react项目之后,需要进行安装react-redux。
react-redux还需要依赖于 Redux 中的 store,所以我们还需要安装 redux。
yarn add react-redux
npm install react-redux
yarn add redux
npm install redux
2.2 利用 redux 来构建 store
-
创建 reducer/index.js 文件,构建reducer来响应actions
//接收两个参数 state action exports.reducer = (state,action)=>{ return state }
-
创建store.index.js文件,通过 createStore 方法,把我们的reducer传入进来
import {legacy_createStore as createStore} from 'redux' //导入reducer import {reducer} from '../reducer' //构建store 直接导出 export default createStore(reducer)
-
在app.js中引入store
2.3 构建页面结构
-
src下创建一个pages目录,里面创建一个组件,名字叫ComA,里面放一个button按钮
import React from 'react' export default class ComA extends React.Component{ render(){ <button> + </button> } }
-
创建另外一个组件,名字叫ComB,里面放一个div,用来显示数字
import React from "react"; export default class ComB extends React.Component{ render(){ return <div>1</div> } }
-
在app.js中引入两个组件
import React from 'react' import './App.css'; //导入我们的store import store from './store' //导入组件A,B import ComA from './pages/ComA'; import ComB from './pages/ComB'; function App() { return ( <div className="App"> <ComA/> <ComB/> </div> ); } export default App;
2.4 引入 Provider 组件
-
在app.js中导入 Provider 组件
import {Provider} from 'react-redux'
-
利用 Provider 组件将我们整个结构进行包裹,并且传递store
functinon App(){ return (<Provider store={store}>...</Provider>) }
-
只要我们把store传递给了 Provider 组件,那么Provider组件就会在内部帮我们维护好 store
//App.js文件中
//导入Provider组件,利用这个组件包裹我们的结构,从而能够达到统一维护store的效果
import {Provider} from 'react-redux'
function App() {
return (
<Provider store={store}>
<div className="App">
<ComA/>
<ComB/>
</div>
</Provider>
);
}
export default App;
2.5 connect-使用
-
导入connect方法
import {connect} from 'react-redux'
-
调用connect方法
connect(...)(Component)
这里是什么意思呢,我们通常知道,调用函数的时候会需要在他后面放一个括号,这里有两个括号,说明什么呢,说明第一个函数执行完之后,返回值还是一个函数,这里其实执行了两次函数,应该就理解了吧。
-
connect方法会有一个返回值,而这个返回值 是一个高阶组件
上面第二个括号中需要传入Component,就是我们自己定义的组件,意思是去加强我们这个组件跟store的联系。所以最终返回值是一个 我们的组件(加强版)
connect的参数说明:
-
哪个组件想要接收数据,就去实现第一个参数,类型是Function
mapStateToProps(state,ownProps)
state:redux中的store ownProps:自己的props
-
哪个组件想要发送action,就去实现第二个参数,类型是Function
mapDispatchToProps(dispatch,ownProps)
dispatch:就是store.dispatch() ownProps:自己的props
那么我们先来思考一下,谁是发送方,谁又是接收方呢,我们上面的案例,靠直觉都能感觉出来对吧,我们点击按钮的时候发送action,我们的ComB就会接收数据来更改页面。ok,那么我们来实践一下。
2.6 利用connect方法让我们的组件与store关联
- 在组件ComA和ComB,分别导入connect方法
- 利用connect方法来对我们组件进行加强,并且导出
- 组件ComA属于发送方,所以要实现第二个参数
- 组件ComB属于接收方,所以要实现第一个参数
A组件(这里的代码 从下往上看)
import React from 'react'
//导入connect
import {connect} from 'react-redux'
class ComA extends React.Component{
handleClick=()=>{
//因为在下方connect方法,将该组件加强,传了这个sendAction()过来
this.props.sendAction()
}
render(){
return <button onClick={this.handleClick}> + </button>
}
}
//这个函数要有一个返回值,是一个对象,会被返回到ComA组件内部 可以被拿到
//dispatch是用来发送action的
const mapDispatchToProps = (dispatch)=>{
return {
sendAction:()=>{
//利用 dispatch 发送一个 action
//传递 action 对象,我们要定义一个type属性
dispatch({
type:'add_action'
})
}
}
}
// 组件A是发送方,要实现connect 第二个参数
// export这个加强版组件,这样App.js拿到的也是加强版的了
export default connect(null,mapDispatchToProps)(ComA)
当然接下来呢,不急着改ComB,先把reducer改了,因为我们上面写了type,reducer里面也得写上,否则没有作用。
reducer
//设置初始值
const initState = {
count: 0
}
//接收两个参数 state action
//接收action,然后进行逻辑处理
exports.reducer = (state = initState, action)=>{
//判断action 是不是我们需要的
switch (action.type){
case 'add_action':
return {count:state.count+1} //返回新的count
default:
return state;
}
}
改完之后呢就可以到B组件里头去接收数据了
ComB
import React from "react";
//导入 connect 方法
import { connect } from "react-redux";
class ComB extends React.Component{
render(){
return <div>{this.props.count}</div>
}
}
//接收两个参数,但第一个是我们最关心的 state
//返回state 在ComB内部,通过this.props.count才能获取到最新数据
const mapStateToProps = (state)=>{
return state
}
//B组件属于接收方,实现 connect的第一个参数
export default connect(mapStateToProps)(ComB)
哦豁,这个时候嘞,在页面上点击加号,下面的数字就会逐次加一了。
转载自:https://juejin.cn/post/7158856944357212190