同一组件中有多个自定义反应挂钩

时间:2020-05-04 13:40:21

标签: javascript reactjs frontend react-hooks jsx

在同一个组件中一个接一个地接两个自定义反应钩子是可以接受的做法吗?

我要处理的问题如下:

将加载第一个自定义钩子useBudgetItems,但随后的钩子是未定义的。我想我理解为什么会发生这种情况(在console.log()语句后加载budgetSettings中的useBudgetSettings属性),但是我不确定该如何解决以及这是否是正确的方法

const BudgetCost ({ projectId }) => {

   const { budgetCost, loaded } = useBudgetCost({ key: projectId });
   const { budgetSettings } = useBudgetSettings({ key: projectId });

   const [totalBudget, setTotalBudget] = useState(budgetCost.totalBudget);
   const [budgetCosts, setbudgetCosts] = useState(budgetCost.items);

   // This will be undefined
   console.log(budgetSettings)

   if(!loaded) return <div/>

   return (
      ...
      ...
   )

});

我的useBudgetCost自定义钩子如下(useBudgetSettings在机制上没有太大区别。

const useBudgetCost = ({ key, notifyOnChange }) => {

    const [loaded, setIsLoaded] = useState(false)
    const { budgetCost, setBudgetCost } = useContext(ProjectContext)

    useEffect(() => {
        if(key)
            return getBudgetCost(key);
    },[key]);

    const getBudgetCost = (key) => {
        let { budgetCosts, loaded } = UseBudgetCostsQuery(key);
        setBudgetCost(budgetCosts);
        setIsLoaded(loaded);
    }

    let onBudgetCostChange = (update) => {
        let tempBudgetCostItems = copyArrayReference(budgetCost);

        tempBudgetCostItems = {
            ...tempBudgetCostItems,
            ...update
        }

        setBudgetCost(tempBudgetCostItems)

        if (notifyOnChange)
            notifyOnChange(update)
    }

    return {
        loaded,
        budgetCost,
        onBudgetCostChange
    }
}

useBudgetSettings组件:

const useBudgetSetting = ({ key }) => {

    const [loaded, setIsLoaded] = useState(false)
    const { budgetSettings, setBudgetSettings } = useContext(ProjectCondext)
    const globalContext = useContext(GlobalReferenceContext);

    useEffect(() => {
        if(key)
            return getBudgetSetting(key);
    },[key]);

    const getBudgetSetting = (key) => {
        let { budgetSettings, loaded } = UseBudgetSettingsQuery(key);
        console.log(budgetSettings);
        setBudgetSettings(budgetSettings);
        setIsLoaded(loaded);
    }

    const getBudgetReferences = (overrideWithGlobal = false) => {
        if(overrideWithGlobal)
            return globalContext.getBudgetReferences();
        return budgetSettings.map((item) => { return { value: item.key, label: item.costCode } });
    }

    const getCategoryText = (key) => _.get(_.find(getBudgetReferences(), (bc) => bc.value === key), 'label');

    return {
        loaded,
        budgetSettings,
        getCategoryText,
        getBudgetReferences
    }
}

0 个答案:

没有答案