有点像这里描述的问题如何比较反应挂钩使用效果的旧值和新值?
但是在我的例子中,useproval
hook没有帮助。
想象一下这个表单有几个输入、选择等等。你可能想看看https://app.uniswap.org/#/swap 进行类似的可视化。几乎任何更改都会发生多个操作和数据更新,这将导致多次重新渲染,至少4次。例如
我有两个输入,每个代表一个标记。基础(第一个)和报价(第二个)。
这是基地的状态
const [base, setBase] = useState({
balance: undefined,
price: undefined,
value: initState?.base?.value,
token: initState?.base?.token,
tokenId: initState?.base?.tokenId,
});
并引用
const [quote, setQuote] = useState({
balance: undefined,
price: undefined,
value: initState?.quote?.value,
token: initState?.quote?.token,
tokenId: initState?.quote?.tokenId,
});
他们会形成一对,比如BTC/USD。
通过更改选择菜单中的令牌
(而不是BTC,我将选择ETH),我将触发多个操作:获取钱包余额、获取价格,并且将有更多的重新提交程序,输入视图更新和模式窗口关闭。因此,目前至少有4起此类事件正在发生。我希望能够比较base。令牌
和basePrv
与const basePrv=useprovian(base?.token)
但在第二次重新渲染
基。令牌
和basePrv
将具有相同的令牌属性,这是一个问题。
我也有输入之间的交换功能,我应该用quote和quote来改变base,就像这样
setBase(prevState => ({
...prevState,
base: quote
}));
setQuote(prevState => ({
...prevState,
quote: base
}));
在这种情况下,不应触发其他请求。
现在,我对它有
use效应
和令牌
依赖关系。但是每次当令牌要更改时,它都会被触发,这将导致额外的异步调用和请求的“尾部”,如果你要快速单击的话。这就是为什么我需要比较更改之前的令牌
属性,以了解我是否应该因为新对的形成(BTC/USD变成ETH/USD)而进行额外的调用和请求,或者我应该忽略它,因为它只是一个"交换”(BTC/USD变成USD/BTC),不需要进行额外的调用和提取。我只是不得不,嗯,交换它们,而不是更多。
因此,在我的故事中,
usePrevious
hook将只返回前一个令牌属性一次,在第二次和第三次时,它将被多个重新呈现(将获取其他属性)覆盖到新的令牌属性。因此,在触发useffect
时,我将没有机会比较上一个令牌属性和当前令牌属性,因为它们将显示相同的属性。
关于如何解决这个问题,我有一些想法,但我不确定这是对还是错,因为在我看来,这些决定看起来更具必要性,而不是陈述性。
>
我可以让一切保持原样(请求总是在任何更改时触发,无论更改是什么。是交换还是用户更改了一对)。我可以禁用交换按钮,直到所有请求都完成。它将解决请求“tail”的问题。但这是一种热修复,这将是可行的,但我不喜欢它,因为它会导致额外的不必要的请求,它将是缓慢的,不利于用户体验。
在由
setBase
或setQuote
更新之前,我可以使用一个状态来保持前一对。它将允许我使用use效应,并将前一对与当前一对进行比较,以了解该对是否已更改,或者只是交换,并决定我是否应该进行读取和调用。
我可以用
base摆脱
和useffect
。令牌报价。标记依赖项,并处理
onClick处理程序中的所有内容。因此,交换功能不会触发
useffect
,只有当用户单击并选择不同的内容时,才会触发调用和获取。但正如我所说,这个选择对我来说似乎有点奇怪。
我试图在这里使用闭包来“记住”令牌的前一个状态,但它有点类似于使用当前组件状态。另外,您必须在功能组件主体之外初始化闭包,我看不出有可能以这种方式将init状态转移到闭包中,因此代码变得更加杂乱无章。
伙计们还有其他想法吗?我肯定错过了什么。也许很多重新渲染是反模式,但我不确定如何避免。
您的问题可能有多种解决方案。我建议选择一个更容易理解的。
您可以修改usePre以往
钩子以在多个呈现中存活。
提示:使用JSON. stringify
比较,如果您认为值将是一个复杂的对象,并且可能会更改引用,即使是相同的实际值。
function usePrevious(value) {
const prevRef = useRef();
const curRef = useRef();
if (value !== curRef.current){
// or, use
// if ( JSON.stringify(value) !== JSON.stringify(curRef.current)){
prevRef.current = curRef.current;
curRef.current = value;
}
return prevRef.current;
}
因为您使用令牌(字符串)作为use效应
的依赖数组,并且您不介意它们的顺序(交换不应该改变任何东西),所以对依赖数组进行排序,如
useEffect(
() => {
// do some effect
},
[base.token, quote.token].sort()
)
在存储API响应数据的同时,还存储与该数据关联的令牌(请求的一部分)。现在,您将有两套代币。
您可以选择仅在当前获取的令牌不能满足您的需要时获取。您还可以扩展此功能,存储以前的API请求/响应,并尽可能从中选择结果。
在所有这些中,第三似乎是个不错的选择
我会选择第二个,因为简单和极简主义。然而,这仍然取决于你在最后发现什么更容易。
我有一个组件,它需要获取数据,将其设置为state,然后将其传递给子级。一些数据还需要在上下文中设置。我的问题是,使用useEffect,一旦调用API,它将为我需要执行的每个setvalue()函数重新呈现。我已经尝试传递useffect一个空的[]数组,由于状态正在改变,仍然得到相同数量的重新渲染。此时数组包含集合。。。用于防止eslint抛出警告的函数。 有没有更好的方法来避免如此多的重新渲
问题内容: 我的目的是观察范围内的模型,并找出旧值和新值之间的差异。 但是,我发现以下代码中的旧值和新值都相同。 输出: 它们为什么相同,如果是故意的,为什么? 这是代码,http://plnkr.co/edit/rfMCF4x6CmVVT957DPSS?p=preview 问题答案: 您可以改用,这似乎可行。如果您还想监视对象上的所有属性(如您所做的那样),则需要将第三个参数添加到监视中。这建立
在下面的代码中,我单击Submit按钮。在backing\u home中,通过ajax调用将布尔值更改为true。 如果我删除渲染的,我会正确地看到更新的输出。但是对于下面的代码,它是。我认为它没有呈现新值 可能是什么原因?
我在树状图中有数据,我使用ObservableList来渲染地图数据。我需要直接在TableView上编辑字符串值。问题是,如何更改TreeMap上的真实数据,即如何从数据列表中获取旧的和新的str值以将其放入map键中。 getOldValue方法不起作用。我用这个方法得到的只是新值。
问题内容: 我有一个名为表,其中有一个名为列,并充满了相同的数字的,等等。 我生成了一个列表,其中包含新的商品编号,它将替换旧的商品编号: 我有一个查询,希望可以解决该查询,但是以某种方式它什么也没做。 (当然,我已将其他值嵌套到查询中) 我如何在这样的列中获取将旧值替换为新值的查询? 问题答案: 您只是在选择新替换的值,而不对它们进行任何操作…在使用replace时,这是一个很好的主意,请始终先
我试图将页面中显示的交易编号与用户单击“无交易”链接后下一页中显示的交易编号进行比较。 我尝试了以下方法: 当我运行此命令时,会出现以下错误: 线程“main”组织中出现异常。openqa。硒。StaleElement引用异常:stale元素引用:元素未附加到页面文档(会话信息:chrome=59.0.3071.115)(驱动程序信息:chromedriver=2.29.461591(62ebf0