安装依赖
npm i redux react-redux
创建 action 文件
action 对象
action 本质是一个 JS 对象,是 store 数据的唯一来源,一般通过 store.dispatch() 将 action 传递到 store,action 对象示例:
{
type: "OPTION_STATE",
data: actionData
}
官方约定 action 必须有一个字符串类型的 type
属性,来表示将要执行的动作。项目较大时,也可以分模块存放 action。官方建议要减少在action中传递数据,例如数组有一项数据,可以只传 idx 下标,然后再检索,比传整个 item 对象过去要好。
action 创建函数
以上面的 action 对象为例,
function optionState() {
return {
type: "OPTION_STATE",
data: actionData
}
}
其实就是将 action对象在函数中返回
一个 action.js 示例:
export const addTask = (id, value) => {
return {
type: "ADD_TASK",
id,
value,
finished: false
}
}
export const deleteTask = (id) => {
return {
type: "DELETE_TASK",
id
}
}
export const clearList = () => {
return {
type: "CLEAR_LIST"
}
}
export const changeFinished = (id, finished) => {
return {
type: "CHANGE_FINISHED",
id,
finished
}
}
创建 reducer 文件示例
reducer 文件返回一个函数,函数接收两个参数,第一个参数是 state
可以指定初始值,代表的是 store 里的某个 state,例如商城App,store里可以有购物车的state,可以有商品列表的state; 第二个参数是action,
接收一个 action 对象,根据action对象的 type 属性来操作当前reducer文件的state(可以通过 combineReducers 合并多个 reducer)
// reducers/product 示例
const product = (state={},action) => {
switch(action.type) {
case "GET_PRODUCT":
return action.product
default:
return state
}
}
export default product
// reducers/cart示例
const defaultState = {}
const cart = (state=defaultState, action) => {
switch(action.type) {
case "ADD_PRODUCT_TO_CART":
return {
}
case "CLEAR_CART":
return defaultState
case "CHANGE_CARTITEMCOUNT":
return {
}
case "DELETE_CARTITEM"
return {
}
default:
return state
}
}
export default cart
// reducers/index.js 合并多个reducer
import { combineReducers } from 'redux'
import product from "./product"
import cart from "./cart"
const ShoppingApp = combineReducers({
product,
cart,
})
export default ShoppingApp
创建 store
// store.js 文件夹示例
import reducer from "../reducers"
import {createStore} from "redux"
const store = createStore(reducer)
export default store
在react 主入口文件下通过 Provider 注册 store
// react 主入口文件 index.js 示例
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import { Provider } from "react-redux"
import store from "./store"
ReactDOM.render(
<Provider store={store}>
<App />
</Provider> ,
document.getElementById('root')
);
在子组件中将 state 和 dispatch 映射到 props
通过 mapStateToProps 和 mapDispatchToProps 函数(其实函数名可以自己随便打,因为最后是通过 connect 函数和组件进行关联)将 state 和 dispatch 映射到 props。
mapStateToProps 函数中返回一个对象,对象属性名就是自己要在props中用的名字,而对象值,就是state 里的值。
mapDispatchToProps 函数中返回一个对象,对象里存放的是将在props中使用的方法,可以进行一系列逻辑处理,逻辑处理完后调用 dispatch 方法,dispatch 方法中传入的是action对象或创建action函数(实际上创建action函数返回的就是一个action对象)
注:通过 combineReducers 合并state后,combineReducers 中各个 state 的名称,就是后面在组件中state调用赋值给 props的依据。
// components/Cart 组件下
import React from "react"
import "./index.css"
import { connect } from "react-redux"
import { changeCartItemCount, clearCart, deleteCartItem, setPromotionValue } from "../../action"
const Cart = ({ cart, countAll, costAll,handleCount, handleDelete, clearCart }) => {
return ()
}
const mapStateToProps = (state) => {
return {
cart: state.cart.productList,
countAll: state.cart.countAll,
costAll: state.cart.costAll,
}
}
const mapDispatchToProps = (dispatch) => {
return {
handleCount: (num, idx, count) => {
if(count < 0 && num === 1) {
return
} else {
dispatch(changeCartItemCount(idx, count))
}
},
handleDelete: (idx) => {
dispatch(deleteCartItem(idx))
},
clearCart: () => {
dispatch(clearCart())
}
}
}
export default connect(mapStateToProps, mapDispatchToProps)(Cart)
另外:mapStateToProps, mapDispatchToProps 都有第二个参数:
ownProps
该参数的具体值是父组件传递给子组件的 props
出错记录:
- If you want to use mapDispatchToProps without a mapStateToProps just use null for the first argument.
export default connect(null, mapDispatchToProps)(Component)
网友评论