什么是React-Redux
React-Redux 是Redux 官方出品的,用于配合React的绑定库。
说到Redux,简单来说它就是一个状态管理库。在多层组件传递props十分繁琐,也会使得组件的数据变得非常混乱,但通过使用Redux,这些问题就能得到解决。
想要学会使用React-Redux 主要有以下几个知识点需要掌握:
- 安装以及起手式
- 搭建页面结构
- 导入provider组件
- 组件A发送 action
- 组件B接收 action
目标效果
我们需要通过React-Redux完成一个页面,它有以下内容:
0 <--初始值
【+1按钮】 <--当我们点击 +1 按钮 的时候,上面的初始值+1
安装以及起手式
安装:
创建一个新的React应用的并附带Redux的时候:
npx create-react-app react-redux-example
在创建好的React中添加Redux:
npm install redux react-redux
接下来是起手式:
在src目录下构建 store 和 reducer
构建reducer
reducer是一个纯函数,它接收之前的state和action作为参数,返回一个更新了的state。
.src/reducer/index.js
,构建该文件作为 reducer 来响应 actions
//接收两个参数
//第一个参数是state
//第二个参数是action
//初始数据
const initialState = {
count: 0
}
//reducer要接受action然后进行逻辑处理的
//判断发送过来的action是不是我们而要的
//如果是我们需要的,就应该 return一个新的state了(以对象的形式)
const reducer = (state = initialState, action) => {
switch (action.type) {
case "add_action":
return { count: state.count + 1}
default:
return state
}
}
export default reducer
构建store
store是react项目中存储state的地方,你可以把它看成是一个大的JavaScript对象。创建store时我们需要一个reducer来作为参数,我们已经创建好reducer了,让我们把它关联到store上面吧。
.src/store/index.js
,通过 createStore 方法 ,把 reducer 传入
//导入createStore方法
import {createStore} form 'redux'
//导入上面编写好的reducer
import {reducer} form '../reducer'
//构建store
export default createStore(reducer)
接下来需要在 app.js
中引入store
(这里我提前把App.js
的结构写好了,App
组件包裹着CompA
和CompB
两个组件)
.scr/App.js
文件
import React from "react"
import "./App.css"
// 导入上面构建好的store
import store from "./store"
//引入组件A
import CompA from './pages/compA.js'
//引入组件B
import CompA from './pages/compB.js'
function App() {
return (
<div className = "App">
<CompA/>
<CompB/>
</div>
)
}
export default App
搭建页面结构
这里为了演示如何使用Redux
,我选取了一个尽量简单的页面结构案例。
创建页面组件A(用来发送action)
./src/pages/CompA.js
//里面暂时先不写东西
创建页面组件B(用来接收A发出的action)
./src/pages/CompB.js
//里面暂时也不写东西
好的,到目前为止,我们有了:
- 一个
reducer
,它接收 action 并且进行相应的处理。 - 一个
store
,它通过 redux 的 createStore 方法使用我们上面的reducer来构建一个store。 - 一个
App.js
文件,它导入了上面创建好的 store。并且在它的<App/>
组件里面,包裹了2个子组件,分别是用来发送 action 的 A组件 和用来接收 action 的 B组件。
导入provider(把store关联到React)
想把store关联到React,我们需要引入一个辅助函数叫做Provider。然后用Provider组件包裹着App组件,再把store作为props值传入Provider。
在App.js
文件中导入provider
,并用它包裹整个应用
还是这个.scr/App.js
文件
import React from "react"
import "./App.css"
// 导入上面构建好的store
import store from "./store"
//这里
//这里
//这里
//多了一步导入Provider组件,并且利用它包裹整个结构 ,从而达到统一维护的目的。
import {Provider} from "react-redux"
//引入组件A
import CompA from './pages/compA.js'
//引入组件B
import CompA from './pages/compB.js'
function App() {
return (
<Provider store = {store}>
<div className = "App">
<CompA/>
<CompB/>
</div>
</Provider>
)
}
export default App
组件A发送 action
action包含着各种类型,比如REMOVE_ARTICLE 或者 ADD_ARTICLE等。它从react组件中被分发(传递数据)到redux 的 store 中。当让action只是一个传递信息的,他不能改变store。store只能被reducer改变。
上面的 ./src/pages/CompA.js
编写好之后是这样子的
class CompA extends React.Component {
handleClick = () =>{
//
this.props.sendAction()
}
render() {
return <button onClick={this.handleClick}> + </button>
}
}
const mapDispatchToProps = dispatch => {
return {
sendAction: () => {
//利用 dispatch 发送一个 action
//传递 action 对象时需要定义一个 type 属性
//返回一个对象
dispatch({
type: "add_action"
})
}
}
}
// A 是发送方,所以要实现 connect 第二个参数
export default connect(null,mapDispatchToProps)(CompA)
在组件A 里面,我们做了这些事情:
- 导入
connect
- 利用
connect
对组件进行加强 - 由于A是发送方,所以需要实现
connect
第二个参数 - 构建了一个函数
mapDispatchToProps(dispatch)
dispatch
就是用来发送action
的 - 在上面这个函数中就可以返回一个对象
key
是方法名(sendAction)
value
(箭头函数):调用dispatch
去发送action
- 在组件中的 内容就可以通过
this.props
来拿到这个方法了。
数据走到了上面的reducer中
通过之前的createStore(reducer)
/*
接收2个参数
第一个是 state
第二个是 action
*/
const initState = {
count: 0
}
// reducer 要接收 action 然后进行逻辑处理
// 它判断 action 的type 如果是我们需要的,则执行对应的行为 (return 一个新的state)
const reducer = (state = initState,action) => {
switch (action.type) {
case "add_action":
return {
count: state.count + 1
}
default :
return state
}
}
export default reducer
组件B 接收 state
import React from "react";
//导入 connect
import { connect } from "react-redux"
class CompB extends React.Component {
render() {
return <div>{this.props.count}</div>
}
}
//接收两个参数
const mapStateToProps = state => {
return state
}
//组件B 是接收方,所以需要实现 connect 方法的第一个参数
export default connect(mapStateToProps)(CompB)
在B组件中,我们做了这些事情:
- 导入
connect
方法 - 利用
connect
对组件进行加强 - 组件B是接收方,所以需要实现
connect
方法的第一个参数 -
mapStateToProps
里面的第一个参数就是我们很关心的state
- 把这个
state
进行return
才能在组件内部获取到最新的数据 - 组件B 是否能拿到数据的关键是
reducer
- 只有
reducer
里面返回了新的state
的时候,我们才能获取到数据。
最终显示效果
0 <--初始值
【+1按钮】 <--当我们点击 +1 按钮 的时候,上面的初始值+1