gpt4 book ai didi

javascript - 如何编写依赖于 React 查询调用的自定义 Hook

转载 作者:行者123 更新时间:2023-12-05 02:41:30 28 4
gpt4 key购买 nike

我有几个钩子(Hook)可以使用 React 查询获取数据并使用该数据进行低级计算。另一个自定义 Hook 将使用该数据的输出来计算不同的值。

例如:

  • Hook #1 获取用户出租属性(property)(例如炉子、屋顶等)的 future 支出 list 。
  • Hook #2 获取用户的偏好,应该考虑和节省 future 多长时间的费用(例如,只有 future 5 年内到期的费用是相关的)。
  • Hook #3 调用 Hook #1 和 #2 并返回每个月应预留以支付 future 费用的总金额。

由于 hook #3 依赖于前两个 hook 的数据,我不确定如何构建该代码。 React 查询返回数据和加载状态,因此我目前正在合并来自 Hook #1 和 #2 的加载状态,并将来自 Hook #3 的数据计算置于条件中。但这会导致重新渲染循环错误。

知道为什么会这样吗?

const usePropertyTotalMonthlyCapex = (propertyId) => {

const [preferences, preferencesIsLoading, preferencesIsError, preferencesError] = useGetUserPreferences()
const [expenses, isLoading, isError, error] = useGetExpenses(propertyId)

const [capex, setCapex] = useState(0)

if (preferences && expenses) { // this seems to be causing a render loop error
if (expenses.length === 0) {
setCapex(0)
} else {
const { outlookLength } = preferences
const expenseValues = expenses?.map(expense => {
const { lifespan, age, replacementCost } = expense
if (lifespan - age > outlookLength) {
return 0
}

return replacementCost / ((lifespan - age) * 12)
})

setCapex(expenseValues.reduce((acc, init) => acc + init).toFixed(0))
}

}

return [capex, preferencesIsLoading && isLoading]

最佳答案

你不需要状态。 capex派生状态,可以根据您已有的状态计算得出。将派生状态放入状态可能是一种反模式。如果您的 useState 的 setter 仅在 effect 中调用,您就可以发现它。由于计算 capex 是纯粹的,您可以在渲染期间调用它:

const computeCapex = (preferences, expenses) => {
if (preferences && expenses) {
if (expenses.length === 0) {
return 0
} else {
const { outlookLength } = preferences
const expenseValues = expenses?.map(expense => {
const { lifespan, age, replacementCost } = expense
if (lifespan - age > outlookLength) {
return 0
}

return replacementCost / ((lifespan - age) * 12)
})

return expenseValues.reduce((acc, init) => acc + init).toFixed(0))
}
}
}

const usePropertyTotalMonthlyCapex = (propertyId) => {

const [preferences, preferencesIsLoading, preferencesIsError, preferencesError] = useGetUserPreferences()
const [expenses, isLoading, isError, error] = useGetExpenses(propertyId)

const capex = computeCapex(preferences, expenses)

return [capex, preferencesIsLoading && isLoading]
}

如果计算量很大,您可以将调用包装在 useMemo 中,这是为此而设计的:

const usePropertyTotalMonthlyCapex = (propertyId) => {

const [preferences, preferencesIsLoading, preferencesIsError, preferencesError] = useGetUserPreferences()
const [expenses, isLoading, isError, error] = useGetExpenses(propertyId)

const capex = React.useMemo(
() => computeCapex(preferences, expenses),
[preferences, expenses]
)

return [capex, preferencesIsLoading && isLoading]
}

关于javascript - 如何编写依赖于 React 查询调用的自定义 Hook ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68100621/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com