I just want to be sure. I have this store in solidjs:
type StoreState = {
selectionByCondition: Array<{
condition: BogoCondition;
cardState: Array<{
handle: string;
variant: string;
}>;
}>;
selectionByReward: Array<{
reward: BogoReward;
cardState: Array<{
handle: string;
variant: string;
checked: boolean;
}>;
}>;
};
I set it like this
setState(
"selectionByReward",
widgetData()?.discountData.rewards.map((reward) => {
console.log({ sortedConditions: sortedConditions() });
if (reward.condition === "SAME_SELECTION") {
if ("match" in reward) {
return {
cardState: state.selectionByCondition[0].cardState.map((v) => ({
...v,
checked: true,
})),
reward,
};
} else if (
"combination" in reward &&
reward.combination === "DIFFERENT_PRODUCTS"
) {
return {
cardState: getCondition(0)
.products.slice(0, reward.quantity)
.map((p) => ({
handle: p.handle,
variant: p.variants[0],
checked: true,
})),
reward,
};
} else {
return {
cardState: new Array(reward.quantity).fill({
handle: getCondition(0).products[0].handle,
variant: getCondition(0).products[0].variants[0],
checked: true,
}),
reward,
};
}
} else {
if (
"combination" in reward &&
reward.combination === "DIFFERENT_PRODUCTS"
) {
return {
cardState: reward.products.slice(0, reward.quantity).map((p) => ({
handle: p.handle,
variant: p.variants[0],
checked: true,
})),
reward,
};
} else {
return {
cardState: new Array(reward.quantity).map(() => ({
handle: reward.products[0].handle,
variant: reward.products[0].variants[0],
checked: true,
})),
reward,
};
}
}
}) || []
);
and I'm trying to update only one 'checked' property of cardState, but I don't know why it's mutating the 'checked' value of all 'checked' of the array, even if it's said in docs that produce should apply localized mutation... What I'm doing wrong ? I cannot mutate the complete array because I trigger fetch when cardState.handle change, and I don't want to trigger a refetch if checked change because it doesn't make sense.
setState(
"selectionByReward",
rewardIdx,
"cardState",
produce((cardState) => {
cardState[cardIndex].checked = !cardState[cardIndex].checked;
})
);
As far as I know produce is used to build the next state using mutations while keeping the original state intact until change is committed. It means once state it committed, you will get a new object. But it does not mean it will mutate an object willy-nilly.
Probably you are mutating multiple items in your code.
The other reason could be the way your are using the produce function. You need to wrap the
producecallback withsetStatefunction like so:Alternatively yo update one or more array items by using their index value or index range:
https://www.solidjs.com/docs/latest#updating-stores