Reducer Hook
一、Reducer Hook
Flux:Facebook出品的一个数据流框架
- 规定了数据是单向流动的
- 数据存储在数据仓库中(目前,可以认为state就是一个存储数据的仓库)
- action是改变数据的唯一原因(本质上就是一个对象,action有两个属性)
- type:字符串,动作的类型
- payload:任意类型,动作发生后的附加信息
- 例如,如果是添加一个学生,action可以描述为:
{ type:"addStudent", payload: {学生对象的各种信息} }
- 例如,如果要删除一个学生,action可以描述为:
{ type:"deleteStudent", payload: 学生id }
- 具体改变数据的是一个函数,该函数叫做reducer
- 该函数接收两个参数
- state:表示当前数据仓库中的数据
- action:描述了如何去改变数据,以及改变数据的一些附加信息
- 该函数必须有一个返回结果,用于表示数据仓库变化之后的数据
- Flux要求,对象是不可变的,如果返回对象,必须创建新的对象
- reducer必须是纯函数,不能有任何副作用
- 该函数接收两个参数
- 如果要触发reducer,不可以直接调用,而是应该调用一个辅助函数dispatch
- 该函数仅接收一个参数:action
- 该函数会间接去调用reducer,以达到改变数据的目的
//useReducer
import { useState } from "react"
/**
* 通用的useReducer函数
* @param {function} reducer reducer函数,标准格式
* @param {any} initialState 初始状态
* @param {function} initFunc 用于计算初始值的函数
*/
export default function useReducer(reducer, initialState, initFunc) {
const [state, setState] = useState(initFunc? initFunc(initialState): initialState)
function dispatch(action) {
const newState = reducer(state, action)
console.log(`日志:n的值 ${state}->${newState}`)
setState(newState);
}
return [state, dispatch];
}
//App
import React from 'react'
import useReducer from './Hooks/useReducer';
function reducer(state,action) {
switch(action.type){
case "increase":
return state+1;
case "decrease":
if(state === 0){
return 0
}
return state - 1
default:
return state;
}
}
export default function App() {
const [n,dispatch] = useReducer(reducer, 10,()=>{
return 100
})
return (
<div>
<button onClick={()=>{
dispatch({type: "decrease"})
}}>-</button>
<span>{n}</span>
<button onClick={()=>{
dispatch({type: "increase"})
}}>+</button>
</div>
)
}
当然,react已经给我们实现,我们可以直接使用
import React,{useReducer} from 'react'
function reducer(state,action) {
switch(action.type){
case "increase":
return state+1;
case "decrease":
if(state === 0){
return 0
}
return state - 1
default:
return state;
}
}
export default function App() {
const [n,dispatch] = useReducer(reducer, 10)
return (
<div>
<button onClick={()=>{
dispatch({type: "decrease"})
}}>-</button>
<span>{n}</span>
<button onClick={()=>{
dispatch({type: "increase"})
}}>+</button>
</div>
)
}
博主开始运营自己的公众号啦,感兴趣的可以关注“飞羽逐星”微信公众号哦,拿起手机就能阅读感兴趣的博客啦!