React学习笔记(5)--订阅与发布

React中的通信方式前面用的比较多的是父子通信。通过父组件将参数作为属性传递给子组件。在编写Web3的前端的时候,不可避免的需要连接钱包,并且需要在组件之间共享钱包的signer以及生成的contract。这个时候,可以把登录按钮写到父组件当中去,然后通过父子通信向子组件传参。比如在父组件中定义一个setState,并把这个setState传递到各个子组件。最开始在父组件中并没有调用这个函数,在子组件中调用setState,就会反过来让父组件重新执行一遍。然后把最新的属性传递到各个子组件当中去。

这种方式在不同子页面之间就不太好传递信息了。另外一种方式是通过订阅发布的形式。将需要共享的变量存储在localStorage中。 并将一个回调函数绑定给对象。每次设置对象的值的时候都会触发相应的回调函数。比如set(address,’address’),先向localStorage中存入该地址,然后触发address对应的回调函数,对这个新的address进行新建contract并查询该地址的余额。这样就实现了参数的共享。

订阅与发布一般是写在一个store.js文件中。这个模板是通用的,只需要在主程序中调用subscribe的时候实例化callback函数就可以了。

function setToLocalStorage(key, value) {
  localStorage.setItem(key, JSON.stringify(value));
}
function getFromLocalStorage(key) {
  const value = localStorage.getItem(key);
  return JSON.parse(value);
}
function removeFromLocalStorage(key) {
  localStorage.removeItem(key);
}

function Store() {
  let store = getFromLocalStorage("store") || {};
  let subscriptions = {};

  function get(name) {
    return store[name];
  }

  function set(name, value) {
    store = { ...store, [name]: value };
    setToLocalStorage("store", store);
    if (subscriptions[name] && subscriptions[name].length) {
      subscriptions[name]
        .filter((callback) => callback !== null)
        .forEach((callback) => {
          callback(value);
        });
    }
  }

  function subscribe(name, callback) {
    if (!subscriptions[name]) {
      subscriptions[name] = [];
    }

    const existing = subscriptions[name].find((cb) => cb === callback);
    if (existing) {
      return () => {};
    }

    const length = subscriptions[name].push(callback);
    const index = length - 1;

    return () => {
      subscriptions[name][index] = null;
    };
  }

  function reset() {
    store = {};
    subscriptions = {};
    removeFromLocalStorage("store");
  }

  return { get, set, subscribe, reset };
}

let storeInstance = {};
if (typeof window !== "undefined") {
  storeInstance = Store();
}

const { get, set, subscribe, reset } = storeInstance;

export { get, set, subscribe, reset };

这个store.js来自国产良心NFT项目的开源代码。

Subscribe to JamesTsao的个人成长笔记
Receive the latest updates directly to your inbox.
Nft graphic
Mint this entry as an NFT to add it to your collection.
Verification
This entry has been permanently stored onchain and signed by its creator.
More from JamesTsao的个人成长笔记

Skeleton

Skeleton

Skeleton