尝试从 API 检索头像图像,但收到头像未定义的错误

发布于 2025-01-11 22:26:57 字数 2522 浏览 1 评论 0原文

userData 是一个使用 getUserByChainAccount 从 API 接收用户数据的函数。 getUserByChainAccount 需要一个用户名,在本例中是从买家动态检索的。

我对 avatar 感兴趣,但我不断收到以下错误未处理的运行时错误 ReferenceError:头像未定义

function UserTransactionsComponent() {
  const [sales, setSales] = useState();

  useEffect(() => {
    async function fetchData() {
      const res = await fetch(
        'https://proton.api.atomicassets.io/atomicmarket/v1/sales'
      );
      const { data } = await res.json();
      setSales(data);
    }
    fetchData();
  }, []);

  if (!sales) {
    return (
      <div>
        <Spinner />
      </div>
    );
  }

  return (
    <PageLayout>
      <ul>
        {sales.map((result) => {
          const {
            sale_id,
            buyer,
            seller,
            listing_price,
            listing_symbol,
            created_at_time,
          } = result;
          const userData = async (buyer) => {
            const user = await proton.getUserByChainAccount(buyer);
            const { name, avatar } = user;
          };

          function HandleBuyerClick() {
            window.location = '/user/' + buyer;
          }
          function HandleSellerClick() {
            window.location = '/user/' + seller;
          }

          if (buyer !== null) {
            return (
              <Card>
                <li key={sale_id}>
                  <h3>
                    <Transaction>
                      {avatar}
                      <Button onClick={HandleSellerClick}>{seller}</Button>
                    </Transaction>{' '}
                    just sold item number
                    <Transaction>
                      <Button>{sale_id}</Button>
                    </Transaction>{' '}
                    to{' '}
                    <Transaction>
                      <Button onClick={HandleBuyerClick}>{buyer}</Button>
                    </Transaction>{' '}
                    for <Transaction>{formatNumber(listing_price)}</Transaction>{' '}
                    {listing_symbol} at {parseTimestampJM(created_at_time)}
                  </h3>
                </li>
              </Card>
            );
          }
        })}
      </ul>
    </PageLayout>
  );
}

export default UserTransactionsComponent;

userData is a function that receives user data from an API using getUserByChainAccount. getUserByChainAccount requires a username, which in this case is dynamically retrieved from buyer.

I'm interested in avatar , but I keep getting the following error Unhandled Runtime Error
ReferenceError: avatar is not defined

function UserTransactionsComponent() {
  const [sales, setSales] = useState();

  useEffect(() => {
    async function fetchData() {
      const res = await fetch(
        'https://proton.api.atomicassets.io/atomicmarket/v1/sales'
      );
      const { data } = await res.json();
      setSales(data);
    }
    fetchData();
  }, []);

  if (!sales) {
    return (
      <div>
        <Spinner />
      </div>
    );
  }

  return (
    <PageLayout>
      <ul>
        {sales.map((result) => {
          const {
            sale_id,
            buyer,
            seller,
            listing_price,
            listing_symbol,
            created_at_time,
          } = result;
          const userData = async (buyer) => {
            const user = await proton.getUserByChainAccount(buyer);
            const { name, avatar } = user;
          };

          function HandleBuyerClick() {
            window.location = '/user/' + buyer;
          }
          function HandleSellerClick() {
            window.location = '/user/' + seller;
          }

          if (buyer !== null) {
            return (
              <Card>
                <li key={sale_id}>
                  <h3>
                    <Transaction>
                      {avatar}
                      <Button onClick={HandleSellerClick}>{seller}</Button>
                    </Transaction>{' '}
                    just sold item number
                    <Transaction>
                      <Button>{sale_id}</Button>
                    </Transaction>{' '}
                    to{' '}
                    <Transaction>
                      <Button onClick={HandleBuyerClick}>{buyer}</Button>
                    </Transaction>{' '}
                    for <Transaction>{formatNumber(listing_price)}</Transaction>{' '}
                    {listing_symbol} at {parseTimestampJM(created_at_time)}
                  </h3>
                </li>
              </Card>
            );
          }
        })}
      </ul>
    </PageLayout>
  );
}

export default UserTransactionsComponent;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

﹂绝世的画 2025-01-18 22:26:57

在渲染期间发出 API 请求是一个众所周知的坏主意。 React 可能会因各种原因重新渲染,例如此组件或任何更新其状态的父组件。在每次渲染时一遍又一遍地重新请求相同的 API 结果是愚蠢的。更不用说尝试将异步操作硬塞到渲染操作中将是困难且容易出错的。

此类请求应在加载组件时发出,并且结果应存储在状态中。

在这种情况下,您最好的选择可能是创建一个完全独立的组件来在 .map() 操作中呈现,并向该组件传递发出 API 请求所需的内容。例如,考虑这样的 .map()

{sales.map((result) => {
  return <SomeOtherComponent result={result} />
})}

然后在组件中,您将处理 API 调用并管理该调用结果的状态。例如,在 SomeOtherComponent 中,您可以这样做:

const {
  sale_id,
  buyer,
  seller,
  listing_price,
  listing_symbol,
  created_at_time,
} = props.result;

const [avatar, setAvatar] = useState(''); // <-- define the state here

useEffect(() => {
  const userData = async (buyer) => {
    const user = await proton.getUserByChainAccount(buyer);
    const { name, avatar } = user;
    setAvatar(avatar); // <--- update the state here
  };
  userData();
}, []);

// define your click handlers as you already do here

// return your JSX markup as you already do here

Making an API request during rendering is a famously bad idea. React might re-render for a variety of reasons, such as this component or any parent component updating its state. It would be silly to re-request the same API results over and over and over on every render. Not to mention that trying to shoehorn asynchronous operations into a render operation is going to be difficult and buggy.

Requests like that should be made when the component is loaded and the results should be stored in state.

In this case your best bet is probably to make an entirely separate component to render within the .map() operation, and pass that component what it needs to make the API request. For example, consider a .map() like this:

{sales.map((result) => {
  return <SomeOtherComponent result={result} />
})}

Then within that component you would handle your API call and manage the state of the result of that call. For example, within SomeOtherComponent you might do this:

const {
  sale_id,
  buyer,
  seller,
  listing_price,
  listing_symbol,
  created_at_time,
} = props.result;

const [avatar, setAvatar] = useState(''); // <-- define the state here

useEffect(() => {
  const userData = async (buyer) => {
    const user = await proton.getUserByChainAccount(buyer);
    const { name, avatar } = user;
    setAvatar(avatar); // <--- update the state here
  };
  userData();
}, []);

// define your click handlers as you already do here

// return your JSX markup as you already do here
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文