为了账号安全,请及时绑定邮箱和手机立即绑定

为什么我的自定义钩子被调用了这么多次?

为什么我的自定义钩子被调用了这么多次?

牧羊人nacy 2021-10-21 17:21:12
我正在尝试实现一个自定义挂钩来为应用程序提供访客购物车。我的钩子环绕着useMutationApollo的钩子,它将购物车 ID 保存在 cookie 中,同时还提供了一个“重置”购物车的功能(基本上,在下订单时删除 cookie)。代码时间!(为简洁起见省略了一些代码):export const useGuestCart = () => {    let cartId;    const [createCart, { data, error, loading }] = useMutation(MUTATION_CREATE_CART);    console.log(`Hook!`);    if (!cartId || cartId.length === 0) {        createCart();    }    if (loading) {        console.log(`Still loading`);    }    if (data) {        console.log(`Got cart id ${data.createEmptyCart}`);        cartId = data.createEmptyCart;    }    const resetGuestCart = useCallback(() => {        // function body here    });    return [cartId, resetGuestCart];};在我的组件中,我只是使用let [cartId, resetCart] = useGuestCart();.当我运行我的单元测试(使用 Apollo 提供模拟突变)时,我看到钩子被调用了几次,输出看起来像这样:console.log src/utils/hooks.js:53    Hook!  console.log src/utils/hooks.js:53    Hook!  console.log src/utils/hooks.js:59    Still loading  console.log src/utils/hooks.js:53    Hook!  console.log src/utils/hooks.js:62    Got cart id guest123  console.log src/utils/hooks.js:53    Hook!  console.log src/utils/hooks.js:53    Hook!我刚刚开始使用钩子,所以我仍然无法理解它们的工作方式。为什么有这么多的钩子调用?谢谢您的回复!
查看完整描述

1 回答

?
LEATH

TA贡献1936条经验 获得超6个赞

将钩子视为直接在组件中具有相同的代码。这意味着每次组件渲染时,钩子都会运行。


例如你定义:


let cartId;

// ...

if (!cartId || cartId.length === 0) {

    createCart();

}

语句中的内容将在每次cartId创建时在每次渲染上运行,并且此时没有分配任何值。而不是使用if语句使用useEffect:


export const useGuestCart = () => {

    const [cartId, setCartId] = useState(0);

    const [createCart, { data, error, loading }] = useMutation(

        MUTATION_CREATE_CART

    );

    const resetGuestCart = () => {

        // function body here

    };


    useEffect(() => {

        if(!cartId || cartId.length === 0){

            createCart();

        }

    }, [cartId]);


    useEffect(() => {

        // Here we need to consider the first render.

        if (loading) {

            console.log(`Started loading`);

        } else {

            console.log(`Finished loading`);

        }

    }, [loading]);


    useEffect(() => {

        // Here we need to consider the first render.

        console.log(`Got cart id ${data.createEmptyCart}`);

        setCartId(data.createEmptyCart);

    }, [data]);


    return [cartId, resetGuestCart];

};

另请注意,useCallback如果未记忆接收函数的组件,则使用没有实际好处。


查看完整回答
反对 回复 2021-10-21
  • 1 回答
  • 0 关注
  • 214 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信