Home > database >  Is this correct way to render according to the state data using async await?
Is this correct way to render according to the state data using async await?

Time:12-23

I got multiple buttons that render different modals. The modals may render different results according to the data provided in the state.

I got 3 state brackets I need to consider

const [cartChangeStoreShow, setCartChangeStoreShow] = useState(false);
const [orderLineId, setOrderLineId] = useState('');
const [storeId, setStoreId] = useState('');

cartChangeStoreShow is for controlling the visible state of the modal

What I want to do is I wanna change OrderLineId and storeId before rendering the component. The data will change according to the orderlineId and storeId.

The component is like this

<CartChangeStorePopUp
        visibility={cartChangeStoreShow}
        setCartChangeStoreShow={setCartChangeStoreShow}
        orderLineId={orderLineId}
        storeId={storeId}
/>

I am calling api inside CartChangeStorePopUp component according to prop data.

So I am handing the user press button like this.

<TouchableOpacity
          onPress={() => renderCartChangeStore(cartItem)}>
            <Text>
              Change Store
            </Text>
 </TouchableOpacity>


const renderCartChangeStore = async cartItem => {
    try {
      await setOrderLineId(cartItem.orderLineId);
      await setStoreId(cartItem.storeId);
    } catch (err) {
      console.log(err);
    } finally {
      setCartChangeStoreShow(true);
    }
  };

the code is working now but from what I read before

Async Await doesn't work properly with setState,So I wanna know if there is potential error with the code written here

CodePudding user response:

To me, it does not make sense both the async/await presence and the try/catch/finally.

Async/await is useful when the function you're calling is dealing with something like I/O, time-consuming, where you cannot do anything than "wait" for the completion. Since "to wait" might be something not desirable in a UI context, the async/await pattern helps you to keep track to the "slow function", but even leave the CPU free to serve other useful tasks.

That being said, the "setXXX" functions of React.useState are not time-consuming: no I/O or similar task involves. Hence, the async/await is not applicable.

Going further, the "setXXX" functions of React.useState throw no error on setting. They're much like setting a variable like so:

var storeId = "";

function setStoreId(value) {
    storeId = value;
}

That is, the try/catch/finally is quite useless.

If you want, you might optimize the code by grouping the three variables as a single immutable object. However, that's up to your real code.

const [storeState, setStoreState] = useState({
    cartChangeStoreShow: false, 
    storeId: "", 
    orderLineId: ""
});

const renderCartChangeStore = cartItem => {
    setStoreState({
        cartChangeStoreShow: true,
        storeId: cartItem.storeId,
        orderLineId: cartItem.orderLineId,
    });
  };

Here is a more compact way to achieve the same behavior:

const renderCartChangeStore = cartItem => {
    setStoreState({
        cartChangeStoreShow: true,
        ...cartItem,
    });
  };

Bear in mind that is very important that you treat the storeState as immutable. That is, never ever change a field of the object, rather create a brand new object with the new field value.

At that point, the component should be called like so:

const handleCartChangeStoreShow = value => {
    setStoreState({
        ...storeState,
        cartChangeStoreShow: value,
    });
}

<CartChangeStorePopUp
        visibility={storeState.cartChangeStoreShow}
        setCartChangeStoreShow={handleCartChangeStoreShow}
        orderLineId={storeState.orderLineId}
        storeId={storeState.storeId}
/>

Notice the handler to correctly alter the storeState object. Worthwhile mention how the new value is set. First, all the current storeState is copied to a fresh new object, then the new show value is also copied on the same object. However, since that happens after, it'll have an override-effect.

  • Related