I have a Wails app (React frontend – Go backend), and I am trying to do the following:
Receive button click -> Do a query on the backend -> receive response from backend -> store response on localStorage -> render page again, so it displays the updated values;
But it only works if I click the query button twice, I believe this happens because I am executing a request and then immediately updating the screen. This leaves me with the question of how to make it so the program awaits for the backend’s response before proceeding to update
function App() {
const query = (_command) => {
QueryBackend(_command)
setState(state + 1)
}
const [state, setState] = useState(0)
return (
<div id="App">
<div>
<p> Hello, World! </p>
<button onClick={() => query('SELECT CODSEN FROM NCMTAB')}>Query a Hello, World!</button>
<ul>
<DebugItem />
</ul>
</div>
</div>
)
};
function QueryBackend(_command) {
Query(_command).then((res) => {
localStorage.setItem('debugItems', res)
})
};
function DebugItem() {
var values = localStorage.getItem('debugItems') || `"empty": "empty"`
return (
<li>{values}</li>
)
};
export default App
I believe I will have to structurally change my code, since I’m not very experienced in React, but I tried searching for answers everywhere (React docs, articles, etc.) and I could not for the life of me find someone that has the same situation as me.
3
Answers
In your current code, the issue arises because you’re calling setState(state + 1) right after invoking QueryBackend(), without waiting for the backend query to complete. React renders the UI before the query is done, which is why you only see the updated values after clicking the button twice.
To solve this, you need to make sure that you update the state and UI after the query response has been received. This can be done using JavaScript’s async/await or then() to wait for the backend’s response before updating the state.
Solution with async/await:
Make query function asynchronous: Use async/await to wait for the backend query to finish before updating the state.
Updating state triggers a React component to re-render, but updating
localStorage
does not. And since your operation is asynchronous and not being awaited, you’re updating state immediately (and re-rendering immediately) and then updatinglocalStorage
sometime later.First, make your
QueryBackend
awaitable (basically have it return aPromise
). For example:Then you can
await
it before updating state:Alternatively, if you want to stick with using
.then()
callbacks, then the function would need to return thatPromise
:And follow it with a callback:
As an aside… This is also a good time to get in the habit of terminating statements with semicolons. JavaScript is forgiving about omitting those, but the result isn’t always what the developer expects. It’s best to be explicit.
I think the code needs little bit of cleanup