0

I have an issue where I think the existing state of a component is being posted via fetch before it has been updated.

This is the function called when submit is clicked:

  function handleSubmit(e) {
    e.preventDefault();
    const html = convertToHTML(editorState.getCurrentContent());
    setData((current) => [...current, { name: name, content: html }]);
    fetch("/api2", {
      method: "POST",
      headers: { "content-type": "application/json" },
      body: JSON.stringify({ parcel: data }),
    });
  }

I think data is being posted before it has been updated via setData.

How do I get the POST method to action after data has been updated?

Drew Reese
  • 165,259
  • 14
  • 153
  • 181
Joseph Walsh
  • 96
  • 1
  • 6
  • You don't have to wait until `data` has been updated, for you already know what data is. Try `const updatedData =[...data,{ name: name, content: html }]; setData(updatedData); fetch("/api2",{ method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ parcel: updatedData })})` – bbbbbbbboat Oct 21 '22 at 17:48

1 Answers1

2

Setting the state is an async operation, and the new state would only be available on the next render. Post the new data to the api in a useEffect block dependent on the data state.

Note: you'll also need to avoid posting on moutn (as noted by bbbbbbbboat's comment). For that you can add a boolean ref the will enable you to skip the mount phase.

const mounted = useRef(false);

function handleSubmit(e) {
  e.preventDefault();
  const html = convertToHTML(editorState.getCurrentContent());
  setData((current) => [...current, { name: name, content: html }]);
}

useEffect(() => {
  if(mounted.current) {
    fetch("/api2", {
      method: "POST",
      headers: { "content-type": "application/json" },
      body: JSON.stringify({ parcel: data }),
    });
  } else {
    mounted.current = true;
  }
}, [data]);

Since you're using data directly when posting, you can also create a temp data, and update both the state and the api:

function handleSubmit(e) {
  e.preventDefault();
  const html = convertToHTML(editorState.getCurrentContent());
  const tempData = [...data, { name: name, content: html }];

  setData(tempData);

  fetch("/api2", {
    method: "POST",
    headers: { "content-type": "application/json" },
    body: JSON.stringify({ parcel: tempData }),
  });
}
Ori Drori
  • 183,571
  • 29
  • 224
  • 209