useReducer的简单使用demo

99 阅读1分钟
import React, { useEffect, useReducer } from "react";
import ReactDOM from "react-dom";
//1,基础版本useReducer,原始数据类型的状态
const reducer = (state, action) => {
  switch (action) {
    case "increment":
      return state + 1;
    case "decrement":
      return state - 1;
    default:
      return state;
  }
};

function Counter() {
  const [count, dispatch] = useReducer(reducer, 0);
  return (
    <div>
      <span>{count}</span>
      <button onClick={() => dispatch("increment")}>+++</button>
      <button onClick={() => dispatch("decrement")}>---</button>
    </div>
  );
} 

//2,对象状态版本的useReducer,可设置不同情况的相加不同的值
const initialState = {
  count1: 0,
  count2: 0,
};
const reducer = (state, action) => {
  switch (action.type) {
    case "increment":
      return { ...state, count1: state.count1 + action.value };
    case "increment2":
      return { ...state, count2: state.count2 + action.value };
    case "decrement":
      return {
        ...state,
        count1: state.count1 - action.value,
      };
    default:
      return state;
  }
};

function Counter() {
  const [countObj, dispatch] = useReducer(reducer, initialState);
  return (
    <div>
      <span>count1-- {countObj.count1}</span>
      <span>count2-- {countObj.count2}</span>
      <button onClick={() => dispatch({ type: "increment", value: 1 })}>
        count1 +1
      </button>
      <button onClick={() => dispatch({ type: "increment2", value: 1 })}>
        count2 +1
      </button>
      <button onClick={() => dispatch({ type: "increment", value: 5 })}>
        +5
      </button>
      <button onClick={() => dispatch({ type: "decrement", value: 1 })}>
        -1
      </button>
    </div>
  );
} 

//3,请求接口 reducer ,原本需要setIsLoading和setData的两个setState可合并到一个reducer中
const initialState = {
  loading: false,
  data: null,
};
const reducer = (state, action) => {
  switch (action.type) {
    case "pending":
      return {
        ...state,
        loading: true,
      };
    case "success":
      return { loading: action.loading, data: action.data };
    case "error":
      return { loading: action.loading, data: action.data };
    default:
      return state;
  }
};

function Counter() {
  const [dataObj, dispatch] = useReducer(reducer, initialState);
  useEffect(() => {
    dispatch({
      type: "pending",
    });
    setTimeout(() => {
      //模拟成功后回调
      dispatch({
        type: "success",
        loading: false,
        data: "res",
      });
    }, 1000);
  }, []);
  return (
    <div>
      <span>isLoading-- {dataObj.loading.toString()}</span>
      <br />
      <span>data-- {dataObj.data}</span>
    </div>
  );
}

function App() {
  return (
    <div>
      <Counter />
    </div>
  );
}

ReactDOM.render(<App />, document.getElementById("root"));