50行封装react - useStore

556 阅读1分钟

定义 store.js 文件

import { useState, useEffect } from 'react';

const listen = [];
let time;
// 初始化 对象
const proxyObj = new Proxy({count: 2}, {
    get(target, key) {
        // console.log(1)
        return target[key];
    },
    set(target, key, value) {
        if (time) {
            clearTimeout(time);
        }
        setTimeout(() => {
            listen.map((fun) => {
                fun.f();
                return true;
            })
        }, 100)
        return Reflect.set(target, key, value);
    }
});

// 修改store值
export function setStore(d) {
    console.log(d)
    const k = Object.keys(d);
    k.map((v) => {
        proxyObj[v] = d[v];
        return true;
    })
}

// 使用store 状态
export function useStore() {
    const [data, setData] = useState({data: proxyObj});
    useEffect(() => {
        const key = new Date().getTime();
        listen.push({key, f: () => {
            setData({data: proxyObj})
        }})
        return () => { // 卸载
            const index = listen.findIndex((item) => item.key = key);
            listen.splice(index, 1); // 删除监听
        };
    }, []);
    return {
        ...data.data, 
        /*setStore(d) {
            const k = Object.keys(d);
            k.map((v) => {
                proxyObj[v] = d[v];
                return true;
            })
        }*/
    }
}

例子:

import React from 'react';
import { useStore, setStore } from './store';

function User1() {
  const data = useStore();
  return (
    <>User1{data.count}</>
  )
}

function User() {
  const data = useStore();
  return (
    <>User{data.count}</>
  )
}

function App(props) {
  const data = useStore();
  return (
    <div className="App">
      test1 _ {data.count}
      <hr/>
      <User/>
      <hr/>
      <User1/>
      
    </div>
  );
}
let c = 1;
function Main(props) {
  console.log(1)
  return (
    <>
      Main 
      <hr/>
      <App/>
      <div onClick={() => {
        setStore({count: c + 1, name: 'age'})
        c = c + 1;
      }}>修改</div>
    </>
  )
}

export default Main;