React code for storing Data from API to an Array and Using the same Array's event_date value for further use.
export const UpcomingHolidays = (props: UpcomingHolidaysProps) => {
const [holidayPlans, setHolidayPlans] = useState([]);
const [dateArray, setDate] = useState([]);
useEffect(() => {
getHolidayPlans();
}, []);
const getHolidayPlans = async () => {
const holidayResp = await PortalHolidayService.getInstance().getHolidayPlans();
if (holidayResp) {
setCities(() => holidayResp.cityModule);
setHolidayPlans(() => holidayResp.holidayModule);
setDate(() => holidayResp.holidayModule);
}
let today = new Date();
console.log(holidayPlans);
holidayPlans.filter((date) => {
const eventDate = new Date(date.event_date);
console.log(eventDate);
});
};
So what the thing is when i use the Same (holidayPlans) array to display some contents in html it shows the values and displays properly but when i use inside a function it shows there is no data inside the array.
Here's a challenge: write a JavaScript function useState
such that the console.log outputs a 4
and then a 5
:
function render() {
let [thing, setThing] = useState(4);
console.log(thing); // 4
setThing(5);
console.log(thing); // 5
}
No matter what you do, you'll never be able to write this function, because no external JavaScript function will be able to set the value of the thing
variable; that's because an external JavaScript has no way to modify the thing
variable. All useState
would be able to do is set its own internal state and change what it returns. Silly example here:
let hiddenState;
function useState(initialValue) {
if (hiddenState === undefined) {
hiddenState = initialValue;
}
const setState = value => {
hiddenState = value;
}
return [hiddenState, setState];
}
That means render
will only be able to get a new value if useState
is called again:
function render() {
let [thing, setThing] = useState(4);
console.log(thing); // 4
setThing(5);
[thing, setThing] = useState(4);
console.log(thing); // 5
}
This is essentially what useState
does but in a way where the hidden state is unique per instance. As you can see, setState
is to be considered "asynchronous" in that state changes aren't reflected until the next render . setState
queues up a re-render request. The next time your render function is called, useState
will be called again, and it will return a new value.
Notice with these code modifications, rather than us referencing the state variable before it has updated, we can still reference your response object to get the data:
export const UpcomingHolidays = (props: UpcomingHolidaysProps) => {
// On the first rendering of `UpcomingHolidays`, holidayPlans will be [].
// After setHolidayPlans is called, a re-render will be queued, and this
// UpcomingHolidays function will be called again. When useState is called
// the second time, it will have the value passed into setHolidayPlans.
const [holidayPlans, setHolidayPlans] = useState([]);
// Same for dateArray.
const [dateArray, setDate] = useState([]);
useEffect(() => {
getHolidayPlans();
}, []);
async function getHolidayPlans() {
const holidayResp = await PortalHolidayService.getInstance().getHolidayPlans();
if (!holidayResp) {
return;
}
// These will flag the component as needing to re-render after the effect
// completes. They do not change the local variables; they update the
// internal data of the useState hooks so that the next time those useState
// calls occur, they'll return new values.
setCities(holidayResp.cityModule);
setHolidayPlans(holidayResp.holidayModule);
setDate(holidayResp.holidayModule.map(date => new Date(date.event_date));
// If you want to log here, don't reference state, which hasn't updated yet.
// Either store response data as variables or reference the response itself.
console.log('Holidays are', holidayResp.holidayModule);
}
return <div>Your content</div>;
}
If you move your console.log(holidayPlans);
out of getHolidayPlans
function, you get an updated value.
export const UpcomingHolidays = (props: UpcomingHolidaysProps) => {
const [holidayPlans, setHolidayPlans] = useState([]);
const [dateArray, setDate] = useState([]);
useEffect(() => {
const getHolidayPlans = async () => {
const holidayResp = await PortalHolidayService.getInstance().getHolidayPlans();
if (holidayResp) {
setCities(holidayResp.cityModule);
setHolidayPlans(holidayResp.holidayModule); // you may filter data here
setDate(holidayResp.holidayModule);
}
};
getHolidayPlans();
}, []);
console.log(holidayPlans);
This happens because when you use the useState
hook, you are assigning the state values holidayPlans
and dateArray
to local constants (or variables, this does not matter), and these values are assigned each time the component is rendered. This means that the constant value in your component will not get updated immediately, but it will be reflected in the next render, which will be triggered by the state updates that you do within getHolidayPlans
. This is why, if you place the console.log()
call outside getHolidayPlans
, the value is printed properly.
export const UpcomingHolidays = (props: UpcomingHolidaysProps) => {
const [holidayPlans, setHolidayPlans] = useState([]);
const [dateArray, setDate] = useState([]);
useEffect(() => {
getHolidayPlans();
}, []);
const getHolidayPlans = async () => {
const holidayResp = await PortalHolidayService.getInstance().getHolidayPlans();
if (holidayResp) {
setCities(() => holidayResp.cityModule);
setHolidayPlans(() => holidayResp.holidayModule);
setDate(() => holidayResp.holidayModule);
}
// ...
};
console.log(holidayPlans);
Basically this is what happens:
First render
|
V
useEffect executes getHolidayPlans()
|
V
getHolidayPlans() performs state changes,
triggering a new render cycle
|
V
Second render,
which will have new state values
It is important to notice that in the end UpcomingHolidays
is just a function, and its body is executed on each render cycle.
Based on this, the recommended way to go is to use constant/variables local to the caller function ( getHolidayPlans()
) instead of using the state constant/variables immediately after their respective setState
function has been called, because they are updated after the completion of the function that it was called in.
export const UpcomingHolidays = (props: UpcomingHolidaysProps) => {
const [holidayPlans, setHolidayPlans] = useState([]);
const [dateArray, setDate] = useState([]);
useEffect(() => {
getHolidayPlans();
}, []);
const getHolidayPlans = async () => {
const holidayResp = await PortalHolidayService.getInstance().getHolidayPlans();
const holidayPlansLocal = holidayResp.holidayModule;
if (holidayResp) {
setCities(() => holidayResp.cityModule);
setHolidayPlans(() => holidayResp.holidayModule);
setDate(() => holidayResp.holidayModule);
}
let today = new Date();
console.log(holidayPlansLocal);
holidayPlansLocal.filter((date) => {
const eventDate = new Date(date.event_date);
console.log(eventDate);
});
};
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.