@web3-react/core vs ethers
Web3 前端架构:钱包连接状态管理与协议交互库的选择
@web3-react/coreethers类似的npm包:

Web3 前端架构:钱包连接状态管理与协议交互库的选择

@web3-react/core 是一个专为 React 设计的钱包连接状态管理库,它通过 Hooks 和 Context 简化了用户钱包连接、切换网络和维护会话状态的流程。ethers 则是一个完整的以太坊协议交互库,提供了签名、交易发送、合约读写等底层能力,不依赖特定前端框架。两者通常配合使用:@web3-react/core 管理 UI 状态,ethers 负责实际的链上操作。

npm下载趋势

3 年

GitHub Stars 排名

统计详情

npm包名称
下载量
Stars
大小
Issues
发布时间
License
@web3-react/core05,68467.6 kB1763 年前GPL-3.0-or-later
ethers08,71313 MB6663 个月前MIT

@web3-react/core vs ethers: 连接状态与协议交互的深度对比

在构建以太坊去中心化应用(dApp)时,开发者常面临一个架构问题:如何管理钱包连接状态,以及如何与区块链交互。@web3-react/core 和 ethers 分别解决了这两个不同层面的问题。前者专注于 React 应用中的连接状态管理,后者专注于以太坊协议本身的交互能力。让我们从实际工程角度对比它们的工作方式。

🔌 钱包连接流程:封装 Hooks vs 手动注入 Provider

@web3-react/core 将钱包连接抽象为 React Hooks。

  • 你不需要直接处理 window.ethereum 注入。
  • 通过 connector.activate() 触发连接,状态自动更新。
  • 适合快速集成多种钱包(如 MetaMask、WalletConnect)。
// @web3-react/core: 使用 Hook 管理连接
import { useWeb3React } from '@web3-react/core';

function ConnectButton() {
  const { account, activate, connector } = useWeb3React();

  const handleConnect = async () => {
    try {
      await activate(connector); // 触发连接
    } catch (error) {
      console.error(error);
    }
  };

  return <button onClick={handleConnect}>连接钱包</button>;
}

ethers 需要手动获取 Provider。

  • 你需要直接访问 window.ethereum。
  • 自行处理连接请求和账户变更事件。
  • 更灵活,但代码量更多,容易出错。
// ethers: 手动创建 Provider
import { BrowserProvider } from 'ethers';

async function connectWallet() {
  if (window.ethereum) {
    const provider = new BrowserProvider(window.ethereum);
    await provider.send('eth_requestAccounts', []); // 请求访问
    const signer = await provider.getSigner();
    const address = await signer.getAddress();
    console.log('Connected:', address);
  }
}

🧠 状态管理:响应式 Context vs 无状态工具

@web3-react/core 内置了状态管理。

  • 账户地址、链 ID、激活状态都保存在 React Context 中。
  • 组件自动重渲染当状态变化(如用户切换网络)。
  • 减少了手动 useState 和 useEffect 的样板代码。
// @web3-react/core: 自动响应状态变化
function AccountDisplay() {
  const { account, chainId, isActive } = useWeb3React();

  if (!isActive) return <div>未连接</div>;
  return <div>{account} - Chain: {chainId}</div>; // 自动更新
}

ethers 是无状态的工具库。

  • 它不提供 UI 状态管理。
  • 你需要自己监听 provider.on('accountsChanged')。
  • 需要手动同步状态到 React 组件。
// ethers: 手动监听状态变化
import { useEffect, useState } from 'react';
import { BrowserProvider } from 'ethers';

function AccountDisplay() {
  const [account, setAccount] = useState(null);

  useEffect(() => {
    if (window.ethereum) {
      const provider = new BrowserProvider(window.ethereum);
      provider.on('accountsChanged', (accounts) => {
        setAccount(accounts[0]); // 手动更新状态
      });
    }
  }, []);

  return <div>{account || '未连接'}</div>;
}

📜 合约交互:提供 Provider vs 实例化合约

@web3-react/core 不直接处理合约。

  • 它提供 provider 对象给其他库使用。
  • 通常配合 ethers 或 viem 一起完成合约调用。
  • 职责单一,只管连接不管业务。
// @web3-react/core: 获取 Provider 供外部使用
import { useWeb3React } from '@web3-react/core';
import { Contract } from 'ethers';

function ReadContract() {
  const { provider } = useWeb3React();
  
  const readData = async () => {
    if (provider) {
      const contract = new Contract(address, abi, provider);
      const value = await contract.readMethod();
      console.log(value);
    }
  };
  // ...
}

ethers 核心功能就是合约交互。

  • 提供 Contract 类来封装 ABI 和地址。
  • 自动处理编码解码、Gas 估算和签名。
  • 是实际执行链上读写的引擎。
// ethers: 实例化并调用合约
import { Contract, BrowserProvider } from 'ethers';

async function callContract() {
  const provider = new BrowserProvider(window.ethereum);
  const signer = await provider.getSigner();
  const contract = new Contract(address, abi, signer);
  
  const tx = await contract.writeMethod(arg); // 发送交易
  await tx.wait(); // 等待确认
}

🌐 多链支持:Hook 参数 vs Provider 切换

@web3-react/core 通过 Hook 参数简化多链。

  • 可以在 activate 时指定链 ID。
  • 状态中直接暴露 chainId 供 UI 判断。
  • 适合需要频繁切换网络的交易类应用。
// @web3-react/core: 切换网络
import { useWeb3React } from '@web3-react/core';

function NetworkSwitcher() {
  const { activate, connector } = useWeb3React();

  const switchToPolygon = () => {
    // 部分连接器支持直接切换链
    activate(connector, undefined, 137); // 137 是 Polygon 链 ID
  };
  // ...
}

ethers 需要手动切换 Provider 实例。

  • 不同链可能需要不同的 RPC URL。
  • 需要自己管理当前选中的网络配置。
  • 更底层,控制力更强但更繁琐。
// ethers: 手动切换 RPC Provider
import { JsonRpcProvider } from 'ethers';

function switchNetwork(chainId) {
  const rpcUrl = getRpcUrl(chainId); // 自定义配置
  const provider = new JsonRpcProvider(rpcUrl);
  // 需要手动更新应用中的 provider 实例
  return provider;
}

🤝 共同点:生态中的互补角色

虽然职责不同,但它们在现代 dApp 架构中紧密合作。以下是关键的重叠与协作点:

1. ⚡ 异步操作支持

  • 两者都基于 Promise 和 async/await 设计。
  • 处理区块链请求时都需要等待网络确认。
// 共同模式:异步等待
// web3-react
await activate(connector);
// ethers
await provider.send('eth_requestAccounts', []);

2. 🔒 安全签名机制

  • 都依赖浏览器注入的钱包进行签名。
  • 私钥永远不离开用户钱包,库只负责请求签名。
// 共同模式:请求签名
// web3-react (通过 provider)
const signature = await provider.send('personal_sign', [msg, account]);
// ethers
const signature = await signer.signMessage(msg);

3. 🛠️ 错误处理

  • 都会抛出标准 JavaScript 错误。
  • 需要开发者捕获并处理用户拒绝或网络错误。
// 共同模式:Try/Catch
try {
  // 操作...
} catch (err) {
  if (err.code === 4001) console.log('用户拒绝');
}

📊 总结:核心差异对比

特性@web3-react/coreethers
核心职责🎨 React 状态管理⚙️ 协议交互引擎
框架依赖⚛️ 必须 React🌐 任意 JS 环境
钱包连接✅ 内置 Hooks 封装❌ 需手动实现
合约调用❌ 需配合其他库✅ 内置 Contract 类
状态同步✅ 自动响应式❌ 手动监听事件
典型场景连接按钮、账户显示交易发送、合约读写

💡 架构建议

@web3-react/core 就像是一个专门的管理员 🧑‍💼,负责维护用户连接状态、处理钱包弹窗和切换网络,让 React 组件能轻松获取当前账户信息。适合用于构建 dApp 的导航栏、连接按钮和用户状态展示。

ethers 就像是一个工程师 🔧,负责实际干活,比如构造交易数据、签名、发送请求到节点并解析返回结果。它是业务逻辑的核心,无论是否使用 React 都不可或缺。

最佳实践:在 React 项目中,通常同时使用两者。用 @web3-react/core 管理连接状态,获取 provider 后传入 ethers 进行实际交互。不要试图用 ethers 手写所有连接逻辑,也不要指望 @web3-react/core 能直接发送交易。各司其职,代码更清晰。

如何选择: @web3-react/core vs ethers

  • @web3-react/core:

    如果你的项目基于 React 且需要标准化的钱包连接流程,选择 @web3-react/core。它封装了复杂的连接器逻辑,提供了 useWeb3React 等 Hooks,让你无需手动管理 provider 注入和状态同步,适合快速构建 dApp 前端界面。

  • ethers:

    如果你需要直接与以太坊区块链交互,如签名消息、发送交易或读取合约数据,必须选择 ethers。它是底层协议库,无论是否使用 React 都需要它(或类似库如 viem),适合处理核心的业务逻辑和链上数据操作。

@web3-react/core的README

@web3-react/core