Home > Software design >  React: how to setData and then post?
React: how to setData and then post?

Time:10-22

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?

CodePudding user response:

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 }),
  });
}
  • Related