0

I have the following state and function

const [obj, setObj] = useState([])

const getData = async (e) => {
      e.preventDefault();
      const text = e.target.input.value;
     const payload = {
        input: text,
      };
      const response = await fetch(process.env.API_LINK, {
        body: JSON.stringify(payload),
        headers: {
          Authorization: `Bearer ${process.env.API_KEY}`,
          "Content-Type": "application/json",
        },
        method: "POST",
      });
      if (response.ok) {
        const data = await response.json();
        const output = data.choices[0].text;
        setObj(obj => [...obj, {input: text, output: output}])
      }
    };

return (
   <form onSubmit={(e) => getData(e)}>
       <input name="input"/>
   </form>
)

The issue is that when the state obj is empty it doesn't get updated when the function first runs, it has to be run twice for obj to be updated. The response from the API and everything else is fine.

devAR
  • 349
  • 7
  • 21
  • Where does the `essay` variable come from? It's in the line where you call `setObj`. – Haroon Azhar Khan May 20 '22 at 06:36
  • @HaroonAzharKhan I was changing the code a bit like changing variable names, to paste it here. forgot to change that one-two. it's fixed now – devAR May 20 '22 at 06:39
  • Are you sure `data.choices[0].text` doesn't produce an error? This will result in a runtime error if `choices` is empty. The rest of the code looks OK. You might misinterpret your observed behavior. – Martin May 20 '22 at 06:40
  • @Martin yes im sure **data.choices[0].text** doesnt cause any errors, i've conole.log'ed it and it gets a proper response every time – devAR May 20 '22 at 06:45
  • How do you know it doesn't get updated the first time? Any chance you do it by inserting a `console.log(obj)` right behind `setObj(obj => [...obj, {input: text, output: output}])`? – Martin May 20 '22 at 06:49
  • @Martin I've ```console.log(obj)``` right after ```setObj(obj => [...obj, {input: text, output: output}])``` and it logs empty like so ```[]```, then when I run it again, obj is updated properly and I can see it in the log – devAR May 20 '22 at 06:55
  • Then this was only caused by your wrong assumptions, the running function still has a reference to the old value, and therefore it prints an empty array. Your state updated alright. Please read this [discussion](https://stackoverflow.com/questions/54069253/the-usestate-set-method-is-not-reflecting-a-change-immediately). – Martin May 20 '22 at 06:59

1 Answers1

-1

Can you try changing setObj call to :

setObj([...obj, {input: text, output: output}])

What you pass to setObj is a function rather than a state obj. It needs to be called hence the changes shows the second time onwards.

  • Just, checked. same issue unfortunately – devAR May 20 '22 at 06:49
  • That answer is incorrect. The given explanation about using a function to determine the new state is wrong. Infact the variant the OP used was correct. – Martin May 20 '22 at 07:05