创建主文件

  1. 根目录src创建reducer文件夹
  2. 文件夹下创建useDataX.js文件
//useDataX.js

import { createContext, useContext, useReducer } from "react";

//? 抛出,创建context上下文,可被访问(通过DataContext.provider的value)
export const DataContext = createContext({});

//? 定义初始值(创建useReducer使用)
const creatData = {
  loading:false
}

//? 抛出,方法可以在普通js中访问
export function dispatchRef(value){
    return {
      current: value
    };
}

//? 这样的形式就叫reducer (通过useReducer传来的值,接收到state:原始值(改变creatData后)、action:变化后的值(dispatch传来的值)
function reducer(state, action) {
  if(action.type==='loading'){
    let stateClone = {...state}  // 这里需要深拷贝复制,可以用JSON.parse(JSON.stringify(state))转化一下
    stateClone.loading=action.value
    return stateClone
  }
}

//? 抛出,可获取DataContext里的value值
export function useData(){
  const { Xdata } = useContext(DataContext);
  return Xdata;
};

// 主函数(可包裹根组件)
export function GlobalLoadingProvider(props) {
  //todo useReducer 接受一个 reducer 函数作为参数,reducer 接受两个参数一个是 state 另一个是 action 。
  //todo 然后返回一个状态 count 和 dispath,count 是返回状态中的值,而 dispatch 是一个可以发布事件来更新 state 的。
  //? 修改dispath后更新dataArr!
  const [dataArr, dispatch] = useReducer(reducer, creatData);
  //? 普通js中访问
  dispatchRef.current = dispatch;
  return (
    <DataContext.Provider value={{ Xdata: dataArr, dispatch }}>
      {props.children}
    </DataContext.Provider>
  );
}

使用

  1. index.js主入口文件添加包裹标签<GlobalLoadingProvider></GlobalLoadingProvider>
//index.js
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App.jsx";
// import reportWebVitals from './reportWebVitals';
import { GlobalLoadingProvider } from "./reducer/useDataX";
ReactDOM.render(
  <React.StrictMode>
    <GlobalLoadingProvider>
      <App />
    </GlobalLoadingProvider>
  </React.StrictMode>,
  document.getElementById("root")
);
  1. 获取数据
import { useData } from "./reducer/useDataX";
function Test() {
  const { loading } = useData();
  return <div>{loading}</div>;
}
export default Test;
  1. 组件内修改数据
import React, { useContext } from "react";

import { DataContext } from "./reducer/useDataX";
function Test() {
  const { dispatch } = useContext(DataContext);
  return (
    <div>
      <button
        onClick={() => {
          dispatch({ type: "loading", value: true });
        }}
      >
        加载
      </button>
    </div>
  );
}
export default Test;
  1. 普通js修改数据
import { dispatchRef } from "../reducer/useDataX";
dispatchRef.current({type:'loading',value:true});

结束

到这里就完成了,引用的时候要注意路径是否正确。现在主文件都是写在一起的,后面业务逻辑复杂后可以做一些封装。


llfididi
281 声望5 粉丝

啊。又是新的一天