如何基于API调用渲染下拉列表

问题描述 投票:0回答:1

我有一个通过调用 API 设置的

contacts
变量。这一切都是在立即调用的函数表达式
(async () => {})();
中完成的。我必须获得令牌才能访问 Microsoft Graph API。这让我可以使用 Office.js 库调用并读取所选电子邮件
await getMessage(microsoftGraphAccessToken...)

我调用自己的 API 端点

getContactsByEmail
contacts
变量包含数据,但
contactDropdown
不显示 - 它只是保留为
<></>

const App = () => {
  let contacts = null;
  let contactDropdown = <></>;

  (async () => {
    let microsoftGraphAccessToken = null;
    let message = null;

    await Office.onReady();

    //Check if Graph is already authorized
    const graphTokenResponse = await graphAuth.getToken(graphLoginRequest);

    microsoftGraphAccessToken = graphTokenResponse.accessToken;

    await getMessage(microsoftGraphAccessToken, Office.context.mailbox.item.itemId, async (data) => {
      message = data;
    });

    const contacts = await getContactsByEmail(message.from.emailAddress.address);

    if (contacts.length > 0) {
      contactDropdown = (
        <select>
          {contacts.map((contact) => (
            <option key={contact.id} value={contact.id}>
              {contact.name}
            </option>
          ))}
        </select>
      );
    }
  })();

  return (
    <div>
      {contactDropdown}
    </div>
  );
}
javascript reactjs jsx outlook-addin office-addins
1个回答
0
投票

无论您使用什么 React 教程,您都忽略了 React 中最基本的概念......状态

变量

contactDropdown
的初始值为
<></>
。这就是组件首次渲染时渲染的内容。然后稍后更新该变量的值。但是,直接更新变量不会触发 React 重新渲染组件。更新 state 即可。

将变量置于状态:

const [contactDropdown, setContactDropdown] = useState(<></>);

然后在稍后需要更新时使用状态设置器:

if (contacts.length > 0) {
  setContactDropdown(
    <select>
      {contacts.map((contact) => (
        <option key={contact.id} value={contact.id}>
          {contact.name}
        </option>
      ))}
    </select>
  );
}

调用状态设置函数告诉 React 在更新状态值后将重新渲染排队。


顺便说一句...... 一般来说在状态中存储标记并不常见。相反,您应该将 data 存储在状态中并在渲染中生成标记。您所拥有的应该可以工作,但如果您需要对这些数据执行其他操作,则很容易遇到问题。

例如,将“联系人”存储在状态:

const [contacts, setContacts] = useState([]);

并用您获取的数据更新它:

const newContacts = await getContactsByEmail(message.from.emailAddress.address);
setContacts(newContacts);

然后使用该 data 在组件中渲染标记:

return (
  <div>
    {contacts.length > 0 ? (
      <select>
        {contacts.map((contact) => (
          <option key={contact.id} value={contact.id}>
            {contact.name}
          </option>
        ))}
      </select>
    ) : <></>}
  </div>
);
© www.soinside.com 2019 - 2024. All rights reserved.