useReducer使用

useReducer

首先創(chuàng)建一個button和n的state

import React,{useState} from "react";
import "./styles.css";

export default function App() {
  const [n,setN] = useState(0)
  const onClick =()=>{
    setN(x=>x+1)
    
  }
  return (
    <div className="App">
      <h1>n: {n}</h1>
      <button onClick={onClick}>+1</button>
    </div>
  );
}
image.png
image.png

1. 創(chuàng)建初始值initalState

const initial ={
  n:0
}

2. 創(chuàng)建所有操作reducer(state,action)

const reducer = (state,action) => {
  if(action.type === 'add') {
    return {n:state.n+1}
  } else if(action.type==='mult') {
    return {n:state.n*2}
  } else {
    throw new Error('error')
  }
}

創(chuàng)建一個帶有+1 和 *2 功能的reducer

3.將創(chuàng)建的reduder傳給userReducer得到讀寫方法

useReducer接受兩個參數(shù),一個是reducer,另一個是initial,

 const [state,dispatch] = useReducer(reducer,initial)
 const {n} = state

返回兩個參數(shù),一個是state保存值,另一個是dispatch


image.png
image.png

取出state中的n后,我們發(fā)現(xiàn)它就是initial中的n.和我們一開始使用的useState的值相同

4. dispatch({type:'操作方法'})

我們修改一下之前的onClick方法,調(diào)用dispatch

const onClick =()=>{  
    dispatch({type:'add'})
  }
image.png
image.png

此時能夠看到,點擊后觸發(fā)了+1的操作,達到了之前useState的setN的效果

我們可以將加的參數(shù)傳給onClick,然后在reducer中增加傳入的參數(shù)

const reducer = (state,action) => {
  if(action.type === 'add') {
    return {n:state.n+action.number}
  } else if(action.type==='mult') {
    return {n:state.n*2}
  } else {
    throw new Error('error')
  }
}

const onClickAdd =(number)=>{  
    dispatch({type:'add',number})
  }

我們再創(chuàng)一個按鈕,用來做乘的操作

 <button onClick={()=>onClickMult(2)}>mult * 2 </button>

修改一下reducer和onClick

 const onClickMult = (number)=>{
    dispatch({type:'mult',number})
  }
 const reducer = (state,action) => {
  if(action.type === 'add') {
    return {n:state.n+action.number}
  } else if(action.type==='mult') {
    return {n:state.n*action.number}
  } else {
    throw new Error('error')
  }
}

先+1,在乘2

image.png
image.png

此時我們的click方法非常的簡單,因為操作被我們聚攏在reducer中,我們在click中只觸發(fā)dispatch,然后調(diào)用相對應(yīng)的reducer

通常情況下,useReducer適合用來處理表單

image.png
image.png
<form onSubmit={onSubmit} onReset={onReset}>
      <div>
        <label>
          姓名
          <input
            value={formData.name}
            onChange={e =>
              dispatch({ type: "patch", formData: { name: e.target.value } })
            }
          />
        </label>
      </div>
      <div>
        <label>
          年齡
          <input
            value={formData.age}
            onChange={e =>
              dispatch({ type: "patch", formData: { age: e.target.value } })
            }
          />
        </label>
      </div>
      <div>
        <label>
          民族
          <input
            value={formData.nationality}
            onChange={e =>
              dispatch({
                type: "patch",
                formData: { nationality: e.target.value }
              })
            }
          />
        </label>
      </div>
      <div>
        <button type="submit">提交</button>
        <button type="reset">重置</button>
      </div>
      <hr />
      {JSON.stringify(formData)}
    </form>

我們可以將reducer分為2個操作,patch(更新任意一項表單),reset(重置所有表單)

const initFormData = {
  name: "",
  age: 18,
  nationality: "漢族"
};

function reducer(state, action) {
  switch (action.type) {
    case "patch":
      return { ...state, ...action.formData };
    case "reset":
      return initFormData;
    default:
      throw new Error();
  }
}
image.png
image.png

我們修改姓名,此時觸發(fā)patch操作

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容