什么是Redux
Redux 是一个数据状态管理仓库,作用与vuex中的store比较类似,以集中式Store的方式对整个应用中使用的状态进行管理,保证了数据状态以一种可预测的方式进行变化
执行流程
Redux的执行流程类似于hooks中的useReducer的执行,如下所示:
store文件的结构
action文件夹下存放的,是要执行的操作;
reducers文件夹下存放的,是数据和要对数据执行的操作;
constants.js文件存储的,是给执行的操作所起的常量名称;
和actions同级的index.js文件存储的,是创建store仓库、搭配第三方插件的操作;
具体执行步骤
准备工作:
constants.js
编写操作中可能用到的操作名称
const SETDATA = 'SETDATA'
export {
SETDATA
}
和actions同级的index.js文件
//applyMiddleware使得react可以使用第三方插件
import {createStore,applyMiddleware} from 'redux'
//导入reducer文件中index.js文件中合并后的reducer
import allReducer from './reducers/index'
//导入支持异步的第三方插件
import thunk from 'redux-thunk'
//创建仓库
//第一个参数为所有reducer
//第二个参数为支持的第三方插件
const store = createStore(allReducer,applyMiddleware(thunk))
export default store
reducer文件合并
在reducer文件夹下创建index.js文件
//导入可以合并reducer操作的模块
import {combineReducers} from 'redux'
//导入reducer文件夹下要合并的reducer文件
import countReducer from './countReduce'
import getlistReduce from './getListReduce'
export default combineReducers({
countReducer,
getlistReduce
})
第一步(React Components):
组件中触发事件,在事件中利用dispatch触发store文件下的action里的文件中的函数
异步:
//导入store文件夹下的action文件夹下的getListAction,解构出setAjaxList
import { setAjaxList } from '../store/actions/getListAction'
//常规导入react
import React,{ useEffect } from 'react'
//导入store仓库
import store from '../store'
//默认暴露Getlist函数
export default function Getlist() {
//相当于componentDidMount调用getList方法
useEffect(()=>{
getList()
},[])
const getList =function() {
//通过dispatch触发action文件夹下文件中的方法(记得调用)
store.dispatch(setAjaxList())
}
return (
<div>
<ul>
//store.getState()方法,获取store中的数据
//后面的.getlistReduce是由于经过了CombineReducer的合并,需要通过.名称来获取
//map用于遍历数据
{store.getState().getlistReduce.map((item,index)=>{
return (
<li>
{item.name}
</li>
)
})}
</ul>
</div>
)
}
同步:
import React,{ useEffect } from 'react'
import axios from 'axios'
import store from '../store'
import { setList,setAjaxList } from '../store/actions/getListAction'
export default function Getlist() {
useEffect(()=>{
getList()
},[])
const getList = async function() {
let {data} = await axios.get("http://elm.cangdu.org/v1/cities?type=hot")
store.dispatch(setAjaxList(data))
}
return (
<div>
<ul>
{store.getState().getlistReduce.map((item,index)=>{
return (
<li>
{item.name}
</li>
)
})}
</ul>
</div>
)
}
第二步(Action Creators):
action受到派发后,执行对应的函数,在函数中进行二次的派发,触发reducer中的操作
异步:
//从contants中导入要执行的操作名称
import { SETDATA } from '../constants'
//导入axios
import axios from 'axios'
//定义setAjaxList函数,获取接口数据
const setAjaxList = (data)=> {
//异步操作,return值为回调函数,函数的参数为dispatch,可以进行异步的派发
return async (dispatch)=>{
//常规axios请求,async、await处理异步问题
let {data} = await axios.get("http://elm.cangdu.org/v1/cities?type=hot")
// 进行异步派发
dispatch({
type:SETDATA,
data
})
}
}
export {
setAjaxList
}
同步:
import { SETDATA } from '../constants'
import axios from 'axios'
// 同步动作
const setList = (data)=> {
return {
type:SETDATA,
data
}
}
export {
setList
}
第三步(Reducer):
action函数中二次派发后,根据reducer里唯一的type,触发对应的操作
异步:
//从contants中导入要执行的操作名称
import { SETDATA } from '../constants'
//定义Ajaxdata数组
let ajaxdata = []
function listReducer(state = ajaxdata,action) {
//从action中解构出type和data
let { type,data } = action
//判断语句,类似于if-else if
//根据传过来的type进行判断
switch (type) {
case SETDATA:
state = data
//这里如果直接写state,页面不会进行更新,需要进行结构后返回
return [...state]
//默认执行返回state的值
default:
return state
}
}
export default listReducer
同步:
import { SETDATA } from '../constants'
let datalist = []
function listReducer(state = datalist,action) {
let { type,data } = action
switch (type) {
case SETDATA:
state = data
return [...state]
default:
return state
}
}
export default listReducer
第四步:
store数据发生改变,页面重新渲染
页面不刷新情况解决
store.subscribe(()=>{
// 可以监听到store数据发生变化
root.render(
<BrowserRouter>
<App />
</BrowserRouter>
);
})
总结
以上,就是我对于redux使用方法的介绍,希望对于刚刚接触redux的新人有所帮助