0
votes

I am trying to immediately update a boolean state variable in react native. the await keyword does not work however. because state setter functions are asynchronous, how can I do this using async / await? In vscode, the await in front of the setLike setter function has a message : "await has no effect on this type of expression"

const likeIt = async () => {
        console.log('like pressed');
        console.log('liked? before set', like);  //**false**
        await setLike(like => !like);
        console.log('liked? after set', like);  //**should be true but getting false**
        const axiosAuth = await axiosWithAuth();
        const userToken = axiosAuth.defaults.headers.Authorization;

        if (like) {
            axiosAuth.post(`https://url`,{})
                .then(res => {
                    console.log('response from post like: ', res.data);
                })
                .catch(err => console.log('error in post like', err.message))
        } else {
            axiosAuth.delete(`https://url`)
                .then(res => console.log('res from unlike', res.data))
                .catch(err => console.log('err from unlike', err))
        }
    }
3

3 Answers

1
votes

await useState(); will not work.

Here is a possible solution that rather works with a temp variable in your likeIt() function.

function App() {
  const [like, setLike] = useState(false);

   const likeIt = async () => {
     let temp = !like;

     const axiosAuth = await axiosWithAuth();
     const userToken = axiosAuth.defaults.headers.Authorization;

    if (!temp) {
      axiosAuth.delete(`https://url`)
              .then(res => console.log('res from unlike', res.data))
              .catch(err => console.log('err from unlike', err))
    } else {
      axiosAuth.post(`https://url`,{})
            .then(res => {
                console.log('response from post like: ', res.data);
            })
            .catch(err => console.log('error in post like', err.message))
    }

    setLike(temp);
}

  return (
    <div className="App">
      <button onClick={likeIt}>{like === true ? 'Liked' : 'Not Liked'}</button>
    </div>
  );
}
0
votes

Are you getting compiling errors due to await setLike()? If not, it is a small issue that would be confusing for some people on VScode. Please kindly check https://github.com/microsoft/vscode/issues/80853

0
votes

If we talk about react hooks, you should to know that useState() return array of two values. The second value is a dispatch function which we use to change value of state. And this functions are synchronous. In your example this dispatch function is setLike() (and it is synchronous function). So await keyword do not work for them actually.

React has special system in the hood to work with changing state. This system wait for batch of changing states and then update our state and rerender component. Before that update of state and rerender of component, our likeIt() function will be done.

You could use useEffect() lifecycle method to handle change of like state.

For example:

const likeIt = async () => {
        console.log('like pressed');
        console.log('liked? before set', like);  //**false**
        await setLike(like => !like);
}

useEffect(() => {
        console.log('liked? after set', like); //**true**
        ...
}, [like]);