通过actions派发修改state状态的桥梁,就是reducer
import * as actionsTypes from './constant'
const initialState = {
counter: 10
}
function reducer(state = initialState, actions) {
switch(actions.type) {
case actionsTypes.ADD_NUMBER:
return {...state, counter: state.counter + actions.num}
case actionsTypes.SUB_NUMBER:
return {...state, counter: state.counter - actions.num}
default:
return state
}
}
export default reducer
单一数据源:
State是只读的:
1. 创建一个对象,作为我们要保存的状态;
2. 创建Store来存储这个state;
5. Redux结构划分;
constant.js 定义type的常量
export const ADD_NUMBER = "add_number"
export const SUB_NUMBER = "sub_number"
createActions.js dispatch派发的actions, 返回一个对象
import * as actionsType from './constant'
export const addNumberActions = (num) => ({
type: actionsType.ADD_NUMBER,
num
})
export const subNumberActions = (num) => ({
type: actionsType.SUB_NUMBER,
num
})
reducer.js 处理派发的actions,返回新的state 实现state状态更新
import * as actionsTypes from './constant'
const initialState = {
counter: 10
}
function reducer(state = initialState, actions) {
switch(actions.type) {
case actionsTypes.ADD_NUMBER:
return {...state, counter: state.counter + actions.num}
case actionsTypes.SUB_NUMBER:
return {...state, counter: state.counter - actions.num}
default:
return state
}
}
export default reducer
index.js 导出reducer
import reducer from "./reducer";
export default reducer
export * from "./createActions"
创建store
import { createStore, applyMiddleware, compose, combineReducers } from 'redux'
import thunk from 'redux-thunk'
import counterReducer from './features/counter'
import homeReducer from './features/home'
import userInfoReducer from './features/userInfo'
const reducer = combineReducers({
counter: counterReducer,
home: homeReducer,
userInfo: userInfoReducer
})
// 打开 redux-devtools {trace: true} 追踪代码执行
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({trace: true}) || compose;
const store = createStore(reducer, composeEnhancers(applyMiddleware(thunk)))
export default store
注意:此图出自coderwhy老师的react课程讲解,有兴趣的小伙伴可以腾讯课堂搜索why老师课程学习
Redux官方文档对于Redux更新state的流程图表述:
前文开头强调redux和react没有直接的关系,在React, Angular, Ember, jQuery, or vanilla JavaScript也完全可以使用Redux。
React官方为了在项目中更高效的使用redux,redux官方提供了react-redux库
npm install react-redux
import { Provider } from 'react-redux'
import store from "./store"
const root = ReactDOM.createRoot(document.querySelector("#root"))
root.render(
)
组件中:
import React, { PureComponent } from 'react'
import { connect } from 'react-redux'
import { addNumberActions, subNumberActions } from '../../store/features/counter'
export class About extends PureComponent {
calcNumber(num, isAdd) {
if(isAdd) {
this.props.addNumber(num)
} else {
this.props.subNumber(num)
}
}
render() {
const { counter, banners, recommends } = this.props
return (
About: counter: {counter}
banners数据:
{
banners.map((item, index) => {
return - {item.title}
})
}
recommends数据:
{
recommends.map((item, index) => {
return - {item.title}
})
}
)
}
}
const mapStateToProps = (state) => ({
counter: state.counter.counter,
banners: state.home.banners,
recommends: state.home.recommends
})
const mapDispatchToProps = (dispatch) => ({
addNumber(num) {
dispatch(addNumberActions(num))
},
subNumber(num) {
dispatch(subNumberActions(num))
}
})
export default connect(mapStateToProps, mapDispatchToProps)(About)
对于网络请求中的数据,需要交给redux来处理,需要通过中间件(middleware)来实现
理解中间件:
npm install redux-thunk
const store = createStore(reducer, applyMiddleware(thunk))
export const fetchHomeMultidataActions = () => {
return (dispatch, getData) => {
axios.get('http://123.207.32.32:8000/home/multidata').then(res => {
const banners = res.data.data.banner.list
const recommends = res.data.data.recommend.list
dispatch(changeBannersActions(banners))
dispatch(changeRecommendsActions(recommends))
})
}
}
import { createStore, applyMiddleware, compose, combineReducers } from 'redux'
const reducer = combineReducers({
counter: counterReducer,
home: homeReducer,
userInfo: userInfoReducer
})