Reputation: 3357
I have a newb question :)
I have a modal that opens in React Native with a dropdown select that requires values. I want to calculate the values whenever the modal opens.
let pickupTime; // Set a value that can be overwritten. I'm not using State because I want this value to change whenever I open the modal again.
const pickupTimeOptions = useRef([{ label: "", value: "" }]); // A ref to store the values
useEffect(() => {
const pickup_hours_today = business.pickup_hours_today; // Array of strings I pass to the modal.
console.log("pickup_hours_today", pickup_hours_today);
const options = pickup_hours_today.map((time) => {
return {
label: time,
value: time,
};
});
pickupTimeOptions.current = options;
}, [business.pickup_hours_today]);
console.log("pickupTimeOptions", pickupTimeOptions); // Let's see if we got it
The problem is that the ref never updates. The log prints this:
pickupTimeOptions Object {
"current": Array [
Object {
"label": "",
"value": "",
},
],
}
pickup_hours_today Array [
... // the string array of hours
]
Should be updating the ref
pickupTimeOptions Object {
"current": Array [
Object {
"label": "",
"value": "",
},
],
}
pickup_hours_today Array [
...
]
Should be updating the ref
What am I doing wrong? Should I handle this differently? I don't mind using state, but when I tried, it kept updating it whenever I selected a different values with the dropdown picker.
Upvotes: 1
Views: 513
Reputation: 11297
If you look at the order of console logs, it'll explain what's happening.
This is printed first, meaning calculation in useEffect
hasn't happened yet
console.log("pickupTimeOptions", pickupTimeOptions); // Let's see if we got it
According to the documentation useEffect
is only called after the render. You need to do the calculation before or during the render cycle.
You can use useMemo
which is executed during rendering. Refer to the documentation for more details
Your updated code should look something like this
let pickupTime; // Set a value that can be overwritten. I'm not using State because I want this value to change whenever I open the modal again.
const pickupTimeOptions = useMemo(() => {
const pickup_hours_today = business.pickup_hours_today; // Array of strings I pass to the modal.
console.log("pickup_hours_today", pickup_hours_today);
const options = pickup_hours_today.map((time) => {
return {
label: time,
value: time,
};
});
return options;
}, [business.pickup_hours_today]);
console.log("pickupTimeOptions", pickupTimeOptions); // Let's see if we got it
Upvotes: 1