首页 > 解决方案 > 反应 | UseCallBack 内的道具未在自定义挂钩内更新

问题描述

我已经构建了一个自定义自定义帖子挂钩,它返回 API 响应和 API 帖子。我正在使用useCallback钩子来设置Response state

出错的地方是钩子Package prop内部没有更新。useCallback

Package当我在钩子外登录时,useCallback我会在属性内获得正确的数据。但是,当我记录钩子Package prop内部时useCallback,值Package不会改变。

不管我按了多少次按钮

我已经尝试创建一个state每次Package prop更新时都会更新的订单,但是每当我在其中设置Package为一个值时,scope我都会得到一个无限循环。

我已经添加Package到钩子scopeuseCallback

例子

  React.useEffect(() => {
    setOrder(Package);
  }, [Package]);

我期望发生的是,每当我调用我的自定义usePostOrder钩子时Package,它内部的useCallback值总是与最新传递的道具保持同步。

自定义钩子

/**
 * custom post hook that returns the API response and the API post function
 * @param {string} url
 * @param {object} Package
 * @returns {array} and @param {function}
 */

export const usePostOrder = (url, Package) => {
  const [loading, setLoading] = React.useState(true);
  const [order, setOrder] = React.useState(Package);
  const [response, setResponse] = React.useState({
    config: {
      data: []
    },
    data: {
      id: 0
    }
  });

  console.log("outside func", Package);
  const postOrder = React.useCallback(async () => {
    console.log("inside func", Package);
  }, [url, loading, Package]);

  return [response, postOrder];
};

Jake Luby 的回答 稍作调整

/**
 * custom post hook that returns the API response and the API post function
 * @param {string} url
 * @param {object} Package
 * @returns {array} and @param {function}
 */

export const usePostOrder = (url, Package, send) => {
  const [postOrder, setPostOrder] = React.useState();
  const [response, setResponse] = React.useState({
    config: {
      data: []
    },
    data: {
      id: 0
    }
  });

  React.useEffect(() => {
    const getData = async send => {
      //this will have the updated input Package
      await axios
        .post(ApiUrl + url, Package)
        .then(function(response) {
          setResponse(response);
        })
        .catch(function(error) {
          setResponse(error);
          console.log(error);
        });
    };

    send && getData();
  }, [send]); //this will run when url or Package changes

  return [response, postOrder];
};

useAsyncEndpoint.PropTypes = {
  url: PropTypes.url,
  user: PropTypes.object,
  club: PropTypes.object,
  cartItems: PropTypes.array
};

我怎么称呼这个钩子

import {usePostOrder} from "./yourHooksFolder"
  const [send, setSend] = React.useState(false);
  const [response, postOrder] = usePostOrder(
    "url",
    createOrder(user, store, cartItems),
    send
  );

  React.useEffect(() => {
    setSend(false);
  }, [response]);

// send order
  const onGoToPaymentPressed = () => {
    setSend(true);
  };



标签: javascriptreactjsreact-nativereact-hooksusecallback

解决方案


useCallback不应该这样使用。它实际上并不运行该函数,它只是将其记忆,以便在渲染之间不会重新创建相同的函数。

您想要的是useEffect钩子并将 postOrder 作为状态的一部分:

export const usePostOrder = (url, Package) => {
  const [postOrder, setPostOrder] = React.useState()
  const [response, setResponse] = React.useState({
    config: {
      data: []
    },
    data: {
      id: 0
    }
  })


  React.useEffect(() => {
    const getData = async url => {
        //this will have the updated input Package
        console.log(Package) 

        //here is where you'll have your REST calls

        //set your data which will then update the return values in the hook and cause a rerender
        setPostOrder(returnValue)
        setResponse(someResponse)
    }

    getData()
  }, [url, Package]) //this will run when url or Package changes

  return [response, postOrder]
}

推荐阅读