Skip to content

coustom hook when taking data in next render lost data

I made a hook useSendFormData , when i use it i get Invalid hook call.

  • Hook takes

  • data from SubmitForm

  • url:string,

  • method: post or put

  • success: succes message if it was success

  • id: not required but if item has id i is added to api call.

  • auth default false

Problem is it loses data on renders i dont know how to describe it better so i made console.log ss As you can see on second call i get data but later its gone…

problem image

My code for this coustom hook:

    const sendFormData = async ({
    auth = false,
  }) => {
    const setPartData = (partialData) => setData({, ...partialData });
    try {
      let response;
      if (method === "post") {
        response = await
          `${SERVER_API}api/v1/${url}/${id ?? ""}`,
      } else if (method === "put") {
        response = auth
          ? await
              `${SERVER_API}api/v1/${url}/${id ?? ""}`,
          : await
              `${SERVER_API}api/v1/${url}/${id ?? ""}`,
        loading: false,
        error: null,
    } catch (err) {
      const { data } = err.response;
        error: data.error,
        success: null,
        loading: false,
    return data;
  return {

And where is use it , it takes data from SubmitForm and make api call with it,as you can see in ss i get there undefined:

const { sendFormData } = useSendFormData()
const handleForm = async (info) => {
  // here you have your returned
  const data = await sendFormData({
    formData: info,
    url: "auth/forgot-password",
    method: "post",
    success: "A password reset message has been sent to your email",

If you could help that would be awesome. If you have any optimatizaion hints for this hook please tell me.Thanks for your time.

Edit: Edit hook but doesnt return data value at the end



const setPartData = (partialData) => setData({, ...partialData });

should be changed to

const setPartData = (partialData) => setData(data => ({, ...partialData }));


setState callback can take either the new state (what you have done), or another callback (what should be done). You should pass a callback like so, to make sure that multiple calls of setPartialData(someData) within sendFormData uses the latest data state to update itself (combining partialData). This approach is necessary as const sendFormData = () => {} is declared, the data variable used within is whatever data was outside the function block (from const [data, setData] = useState() ). This data is not updated as sendFormData() runs, instead only on the end of a component render cycle.

In other words,

const [data, setData] = useState(initialData);
const sendFormData = () => {
  const setPartData = (partialData) => setData({, ...partialData });
  setPartData(data1); // combines with initialData
  setPartData(data2); // combines with initialData as well

Note that where you declare const setPartData does not matter, as long as it has access to the data scope.

On the other hand,

const setPartData = (partialData) => setData(data => ({, ...partialData }));

uses the latest data state when setData() needs to run, by accessing it through the internal callback.

Since the hook you built can return the data state, once it is updated correctly, you can now use it like this in a better manner.

// App.js
const {data, sendFormData} = useSendFormData();
const sendAction = async (arg) => await sendFormData(arg);
return <>
  <button onClick={sendAction}>send data</button>
  { data.success || someCondition ? data : null }

It’s probably not a good idea to reinvent the wheel when this swr library exists, but I commend your effort in trying to make code DRY.