redux 相关安装
- yarn add redux
- yarn add react-redux
react对redux的友好支持
- yarn add redux-thunk
redux 异步中间件
- yarn add redux-logger
redux 操作日志
redux 组成
- state
存储属性
- action
action对象 - 负责告知store要执行的动作
- reducer
根据action动作,进行相应处理,并将处理后的数据返回store
项目结构
- src
- components UI组件
- counter
- index.js
- pages 页面
- counter
- index.js
- store 仓库
- action
- xxxaction.js
- reducer
- xxxreducer.js
- index.js
- index.js
- App.js
示例【1】 action创建函数
// store/action/counter.js
// 定义action type 对应枚举值, ts友好
export const actionType = {
ADD: 'ADD'
}
// action 创建函数 - 通过action创建函数 返回一个action对象
// 亦可省略action创建函数。 直接使用action对象
export const addCount = (count) => {
return {
type: actionType.ADD,
count
}
}
示例【2】 单个reducer
// store/reducer/counter.js
import { actionType } from '../action/counter.js'
const counter = (state = 0, action) => {
switch(action.type){
case actionType.ADD:
return state + action.count;
default:
return state;
}
}
export default counter
示例【3】 合并多个reducer并输出
// store/reducer/index.js
import { combineReducers } from 'redux'; // combineReducers 合并多个reducer
import counterReducer from './counter.js'
export default combineReducers({
// counterReducer, // 方式1
counter: counterReducer, // 方式2 别名
})
示例【4】 将reducer挂载到store仓库
// store/index.js
import { createStore, applyMiddleware } from 'redux'
import thunkMiddleware from 'redux-thunk'
import { createLogger } from 'redux-logger'
import RootReducers from './reducers/index.js'
export default createStore(RootReducers, applyMiddleware(
thunkMiddleware, // 异步支持
createLogger(), // 操作日志
))
上述4个示例通过redux依赖帮助我们建立了store,接下来需要用到react-redux在UI组件或页面中进行使用
react-redux 示例【1】
// App.js
// Provider 容器 - 被该容器包裹的组件或页面 才可以使用react-redux相关的功能
// 且被 Provider 容器包裹后的组件或页面 其 子孙组件同样可使用react-redux
import { Provider } from 'react-redux'
import store from './store' // store 仓库
import counterPage from './pages/counter/index' // 页面
function App() {
return (
<Provider store={store}>
<div className="App">
<counterPage />
</div>
</Provider>
);
}
react-redux 示例【2】
// pages/counter/index.js
import Counter from '../../components/counter/index'
const counterPage = () => {
return (
<div className="counter-page">
页面其他内容 ...
<Counter />
页面其他内容 ...
</div>
);
}
export default counterPage
react-redux 示例【3】
// components/counter/index.js
import { connect } from 'react-redux'
import { addCount } from '../../store/action/counter.js'
const Counter = (props) => {
// 通过connect后 该组件props 中便具备了 mapStateToProps 及 mapDispatchToProps中的属性及方法
const { count, add } = props;
return (
<div className="counter">
<span>{count}</span>
<button onClick={() => add(1)}>增加</button>
</div>
);
}
// mapStateToProps 是一个映射关系, 即 将定义的某个key的值 与 store中的某个属性进行映射
const mapStateToProps = (state) => {
return {
count: state.counter, // combineReducer时使用了别名 即 counter
}
}
// dispatch 接收一个action对象
// 我们通过action创建函数 生成一个action对象 并提供给dispatch
const mapDispatchToProps = (dispatch) => {
return {
add: (val) => dispath(addCount(val))
}
}
export defalut connect(mapStateToProps, mapDispatchToProps)(Counter)
到此 redux 及 react-redux 的基本使用变完成了。 小白初学,如果上述有问题欢迎留言指证,您的一次指证或许能帮助更多的人少走很多的弯路 哈哈~
注: 上面有引入thunk,但示例中并未有异步的例子
另外 附上 redux 的中文文档 里面有更详细的介绍redux 的各种使用