在 hooks 中提供了的 useReducer 功能灵迫,可以增強(qiáng) ReducerDemo 函數(shù)提供類似 Redux 的功能就缆,引入 useReducer 后宪萄,useReducer 接受一個(gè) reducer 函數(shù)作為參數(shù)州叠,reducer 接受兩個(gè)參數(shù)一個(gè)是 state 另一個(gè)是 action 后众。然后返回一個(gè)狀態(tài) count 和 dispath放闺,count 是返回狀態(tài)中的值祟昭,而 dispatch 是一個(gè)可以發(fā)布事件來(lái)更新 state 的。
import React,{useReducer} from 'react'
export default function ReducerDemo() {
const [count, dispath] = useReducer((state,action)=> {
//...
}, 0);
return (
<div>
<h1 className="title">{count}</h1>
</div>
)
}
- 在 useReducer 傳入 reducer 函數(shù)根據(jù) action 來(lái)更新 state怖侦,如果 action 為 add 正增加 state 也就是增加 count从橘。
在 button 中調(diào)用 dispatch 發(fā)布 add 事件,發(fā)布 add 事件后就會(huì)在 reducer 根據(jù)其類型對(duì) state 進(jìn)行對(duì)應(yīng)操作础钠,更新 state恰力。
export default function ReducerDemo() {
const [count, dispath] = useReducer((state,action)=> {
if(action === 'add'){
return state + 1;
}
return state;
}, 0);
return (
<div>
<h1 className="title">{count}</h1>
<button className="btn is-primary"
onClick={()=> dispath('add')}
>Increment</button>
</div>
)
}
下面的代碼并不沒(méi)有什么特別,只是在上面代碼基礎(chǔ)進(jìn)行鞏固旗吁,大家可以自己閱讀一下踩萎。
import React,{useReducer} from 'react'
export default function ReducerDemo() {
const [count, dispath] = useReducer((state,action)=> {
switch(action){
case 'add':
return state + 1;
case 'sub':
return state - 1;
default:
return state;
}
}, 0);
return (
<div>
<h1 className="title">{count}</h1>
<button className="btn is-primary"
onClick={()=> dispath('add')}
>Increment</button>
<button className="btn is-warnning"
onClick={()=> dispath('sub')}
>Decrement</button>
</div>
)
}
在下面的代碼中 action 不再是字符串而變成對(duì)象,通過(guò) type 來(lái)表示 action 類型很钓,然后通過(guò) name 來(lái)帶來(lái)更多的信息香府。其實(shí)這些代碼雖然變得復(fù)雜但是本質(zhì)和上面分享內(nèi)容并沒(méi)有什么不同。
import React,{ useReducer,useRef } from 'react'
export default function ShoppingList() {
const inputRef = useRef();
const [items, dispatch] = useReducer((state,action)=> {
switch(action.type){
case 'add':
return [...state,
{
id:state.length,
name:action.name
}]
}
},[])
function handleSubmit(event){
event.preventDefault();
dispatch({
type:'add',
name:inputRef.current.value
});
inputRef.current.value = '';
}
return (
<>
<form onSubmit={handleSubmit}>
<input ref={inputRef}/>
</form>
<ul>
{items.map(item => (
<li key={item.id}>{item.name}</li>
))}
</ul>
</>
)
}
這里值得說(shuō)一下就是 ...state 這是每一次我們需要 copy 一個(gè) state 然后修改 state 而不是在 state 原有對(duì)象進(jìn)行修改码倦。這就是 immutable 數(shù)據(jù)吧企孩。
import React,{ useReducer,useRef } from 'react'
export default function ShoppingList() {
const inputRef = useRef();
const [items, dispatch] = useReducer((state,action)=> {
switch(action.type){
case 'add':
return [...state,
{
id:state.length,
name:action.name
}]
case 'remove':
return state.filter((_,index) => index != action.index)
case 'clear':
return [];
default:
return state;
}
},[])
function handleSubmit(event){
event.preventDefault();
dispatch({
type:'add',
name:inputRef.current.value
});
inputRef.current.value = '';
}
return (
<>
<form onSubmit={handleSubmit}>
<input ref={inputRef}/>
</form>
<button
className="button is-danger"
onClick={
() => dispatch({type:'clear'})
}>clear</button>
<ul>
{items.map((item,index) => (
<li className="section" key={item.id}>{item.name}
<button className="button" onClick={
() => dispatch({type:'remove',index})
}>X</button>
</li>
))}
</ul>
</>
)
}