React | реквизиты внутри UseCallBack не обновляются внутри пользовательского хука

Я создал настраиваемый обработчик сообщений, который возвращает ответ API и сообщение API. И я используюuseCallback крючок, чтобы установить Response state

Что не так, так это то, чтоPackage prop не обновляется внутри useCallback крючок.

Когда я вхожу Package вне useCallbackкрючок я получаю нужные данные внутри свойства. Однако когда я регистрируюPackage prop внутри useCallback зацепить ценность Package не меняется.

Независимо от того, сколько раз я нажимаю кнопку

Я пробовал создать заказstate который обновляется каждый раз, когда Package prop обновления, однако всякий раз, когда я устанавливаю Package как ценность в scope Получаю бесконечный цикл.

Я также добавил Package в scope из useCallback крюк

пример

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

Я ожидаю, что когда- нибудь я назову свой обычайusePostOrder зацепить ценность Package что внутри useCallback всегда в курсе последних переданных реквизитов.

CustomHook

/**
 * 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];
};

Ответ Джейка Луби с небольшой поправкой

/**
 * 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);
  };



1 ответ

Решение

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]
}
Другие вопросы по тегам