我有一个通过调用 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>
);
}
无论您使用什么 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>
);