react_hooks系列07_useReducer

69 阅读1分钟

useState 的替代方案。它接收一个形如 (state, action) => newState 的 reducer,并返回当前的 state 以及与其配套的 dispatch 方法。

1)、userReducer可以把数据和对数据的处理进行封装,每个组件(或者模块)都可以使用。

2)、userReducer 就是跟redux里的思路一样。

基本使用:

import React, { useReducer } from 'react';
 
// 1、定义一个初始值(数据)
const initState= {count:5}
 
// 2、定义一个reducer(对数据的操作)
function reducer(state,action){
    switch(action.type){
        case "inc":return {count:state.count+1};
        case "dec":return {count:state.count-1};
        default:throw new Error();
    }
}
 
export default function UseReducer() {
 
   const [state,dispatch]= useReducer(reducer,initState);
   
    console.log("组件:state",state);
    return (
        <>
            <div>useReducer</div>
            <p>state.count:{state.count}</p>
            <input type="button" value="count的加法" onClick={()=>dispatch({type:"inc"})} /><br />
            <input type="button" value="count的减法" onClick={()=>dispatch({type:"dec"})} />
        </>
    )
}

使用useReducer和useContext可以实现一个轻型的redux

import React, { Component } from "react";
import { useEffect } from "react";
import { useContext } from "react";
import { createContext, useReducer } from "react";
 
const MyContext = createContext();
 
const initialState = {
  bannerList: [],
  proList: [],
};
 
const reducer = (state, action) => {
  const { type, payload } = action;
  switch (type) {
    case "CHANGE_PRO_LIST":
      return { ...state, proList: payload };
    default:
      return state;
  }
};
 
const Child1 = () => {
  const { state, dispatch } = useContext(MyContext);
    
  useEffect(() => {
    dispatch({ type: "CHANGE_PRO_LIST", payload: [{ proid: "01001",proname:"铅笔" }] });
  }, []);
 
  return (
    <div>
      {state.proList &&
        state.proList.map((item) => {
          return <p key={item.proid}>{item.proname}</p>;
        })}
    </div>
  );
};
 
 
const App = () => {
  const [state, dispatch] = useReducer(reducer, initialState);
  return (
    <MyContext.Provider value={{ state, dispatch }}>
      <Child1 />
    </MyContext.Provider>
  );
};
 
export default App;