当存在我不关心的依赖项时如何使用 useEffect?
How to use useEffect when there are dependencies I don't care about?
useCallback(() => {
async function awaitAllPendingTxs() {
const txReceiptPromises = txsPending.map((tx) => {
return provider.waitForTransaction(tx.hash);
});
const txReciepts = await Promise.all(txReceiptPromises);
txReciepts.forEach((tx) =>
dispatch(actions.rmTxsPending(tx.transactionHash))
);
}
awaitAllPendingTxs();
}, [provider]);
我只希望在应用首次加载时 运行。
更具体地说,当 provider
可用时。 provider
被初始化为 null
。在应用首次加载时的某个时刻,provider
被初始化。那就是我想要 运行.
的时候
但是 React hooks 插件告诉我添加 dispatch
和 txsPending
.
我不希望代码在 txsPending
和 dispatch
更改时变为 运行。然而,我需要 useCallback
.
中的这些变量和函数
如果我在dep数组中加上txsPending
和dispatch
,代码块不会被调用3次吗?
dispatch创建一次,每次txsPending
改变(txsPending
是localstate)?我不想要。
这里useCallback
dep数组是怎么满足的?同时还要确保它只在我需要时 运行s?
最佳做法是在使用 useEffect
时不要对依赖项数组撒谎,因为它可能会在以后引起问题。
试试这个:
const [avoidExtraCall, setAvoidExtraCall] = useState(false);
useCallback(() => {
if(provider && !avoidExtraCall){
async function awaitAllPendingTxs() {
const txReceiptPromises = txsPending.map((tx) => {
return provider.waitForTransaction(tx.hash);
});
const txReciepts = await Promise.all(txReceiptPromises);
txReciepts.forEach((tx) =>
dispatch(actions.rmTxsPending(tx.transactionHash))
);
}
awaitAllPendingTxs();
setAvoidExtraCall(true);
}
}, [provider, txsPending]);
你能做的最好的事情就是在 useRef
中存储(或克隆)txsPending
,并在适当的时候更新值,这样 useEffect
就可以一直拥有最新值。
对于dispatch
我猜它的值总是静态的,所以它可以被闭包安全地捕获;但是 eslint 没有正确解析它。我想你可以忽略它,如果你接受保留 eslint 警告,否则你可能还需要将它克隆到 useRef
.
P.S。我想你的意思是 useEffect
而不是 useCallback
?既然你没有将 useCallback
的结果分配给任何变量供以后使用?
代码:
useEffect(() => {
async function awaitAllPendingTxs() {
// This line, use a ref
const txReceiptPromises = txsPendingRef.current.map((tx) => {
...
// ignore warning, or use something like dispatchRef.current
txReciepts.forEach((tx) =>
dispatch(actions.rmTxsPending(tx.transactionHash))
);
}
awaitAllPendingTxs();
}, [provider]);
useCallback(() => {
async function awaitAllPendingTxs() {
const txReceiptPromises = txsPending.map((tx) => {
return provider.waitForTransaction(tx.hash);
});
const txReciepts = await Promise.all(txReceiptPromises);
txReciepts.forEach((tx) =>
dispatch(actions.rmTxsPending(tx.transactionHash))
);
}
awaitAllPendingTxs();
}, [provider]);
我只希望在应用首次加载时 运行。
更具体地说,当 provider
可用时。 provider
被初始化为 null
。在应用首次加载时的某个时刻,provider
被初始化。那就是我想要 运行.
但是 React hooks 插件告诉我添加 dispatch
和 txsPending
.
我不希望代码在 txsPending
和 dispatch
更改时变为 运行。然而,我需要 useCallback
.
如果我在dep数组中加上txsPending
和dispatch
,代码块不会被调用3次吗?
dispatch创建一次,每次txsPending
改变(txsPending
是localstate)?我不想要。
这里useCallback
dep数组是怎么满足的?同时还要确保它只在我需要时 运行s?
最佳做法是在使用 useEffect
时不要对依赖项数组撒谎,因为它可能会在以后引起问题。
试试这个:
const [avoidExtraCall, setAvoidExtraCall] = useState(false);
useCallback(() => {
if(provider && !avoidExtraCall){
async function awaitAllPendingTxs() {
const txReceiptPromises = txsPending.map((tx) => {
return provider.waitForTransaction(tx.hash);
});
const txReciepts = await Promise.all(txReceiptPromises);
txReciepts.forEach((tx) =>
dispatch(actions.rmTxsPending(tx.transactionHash))
);
}
awaitAllPendingTxs();
setAvoidExtraCall(true);
}
}, [provider, txsPending]);
你能做的最好的事情就是在 useRef
中存储(或克隆)txsPending
,并在适当的时候更新值,这样 useEffect
就可以一直拥有最新值。
对于dispatch
我猜它的值总是静态的,所以它可以被闭包安全地捕获;但是 eslint 没有正确解析它。我想你可以忽略它,如果你接受保留 eslint 警告,否则你可能还需要将它克隆到 useRef
.
P.S。我想你的意思是 useEffect
而不是 useCallback
?既然你没有将 useCallback
的结果分配给任何变量供以后使用?
代码:
useEffect(() => {
async function awaitAllPendingTxs() {
// This line, use a ref
const txReceiptPromises = txsPendingRef.current.map((tx) => {
...
// ignore warning, or use something like dispatchRef.current
txReciepts.forEach((tx) =>
dispatch(actions.rmTxsPending(tx.transactionHash))
);
}
awaitAllPendingTxs();
}, [provider]);