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.