来自 API 调用的数据存储在数组中,但是当我尝试在函数中使用该数组以供进一步使用时,它显示该数组为空。为什么?
Data from API call are stored in a Array but when i try to use that array in a function for further use it shows that array is empty . why?
React 将数据从 API 存储到数组 并使用 相同数组的 event_date 值 供进一步使用。
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);
});
};
所以当我使用 Same (holidayPlans) 数组在 html 中显示某些内容时,它显示了值并正确显示,但是当我在函数内部使用时,它显示内部没有数据数组 .
console.log(holidayPlans) shows this
Same Array used to display in html
如果您将 console.log(holidayPlans);
移出 getHolidayPlans
函数,您将获得更新后的值。
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);
这是一个挑战:编写一个 JavaScript 函数 useState
使得 console.log 输出一个 4
然后一个 5
:
function render() {
let [thing, setThing] = useState(4);
console.log(thing); // 4
setThing(5);
console.log(thing); // 5
}
无论你做什么,你永远无法编写这个函数,因为没有外部JavaScript函数能够设置thing
变量的值;那是因为外部 JavaScript 无法修改 thing
变量。 useState
所能做的就是设置它自己的 内部 状态并更改它 return 的状态。愚蠢的例子在这里:
let hiddenState;
function useState(initialValue) {
if (hiddenState === undefined) {
hiddenState = initialValue;
}
const setState = value => {
hiddenState = value;
}
return [hiddenState, setState];
}
这意味着render
只有在再次调用useState
时才能得到一个新值:
function render() {
let [thing, setThing] = useState(4);
console.log(thing); // 4
setThing(5);
[thing, setThing] = useState(4);
console.log(thing); // 5
}
这本质上就是 useState
所做的,但是隐藏状态在每个实例中都是唯一的。如您所见,setState
被认为是“异步的”,因为状态更改不会反映 直到下一次渲染 。 setState
排队 re-render 请求。下次你的 render 函数被调用时,useState
会被再次调用,它会 return 一个新的值。
注意这些代码修改,而不是我们在更新之前引用状态变量,我们仍然可以引用您的响应对象来获取数据:
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>;
}
发生这种情况是因为当您使用 useState
挂钩时,您正在将状态值 holidayPlans
和 dateArray
分配给局部常量(或变量,这无关紧要),并且每次渲染组件时都会分配这些值。这意味着组件中的常量值不会立即更新,但会反映在下一次渲染中,这将由您在 getHolidayPlans
内执行的状态更新触发。这就是为什么如果您将 console.log()
调用放在 getHolidayPlans
之外,该值会正确打印。
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);
基本上是这样的:
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
重要的是要注意最后 UpcomingHolidays
只是一个函数,它的主体在每个渲染周期执行。
基于此,推荐的方法是使用调用函数 (getHolidayPlans()
) 本地的 constant/variables,而不是在各自的 [= 之后立即使用状态 constant/variables 21=] 函数已被调用,因为它们在调用它的函数完成后更新。
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);
});
};
React 将数据从 API 存储到数组 并使用 相同数组的 event_date 值 供进一步使用。
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);
});
};
所以当我使用 Same (holidayPlans) 数组在 html 中显示某些内容时,它显示了值并正确显示,但是当我在函数内部使用时,它显示内部没有数据数组 .
console.log(holidayPlans) shows this
Same Array used to display in html
如果您将 console.log(holidayPlans);
移出 getHolidayPlans
函数,您将获得更新后的值。
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);
这是一个挑战:编写一个 JavaScript 函数 useState
使得 console.log 输出一个 4
然后一个 5
:
function render() {
let [thing, setThing] = useState(4);
console.log(thing); // 4
setThing(5);
console.log(thing); // 5
}
无论你做什么,你永远无法编写这个函数,因为没有外部JavaScript函数能够设置thing
变量的值;那是因为外部 JavaScript 无法修改 thing
变量。 useState
所能做的就是设置它自己的 内部 状态并更改它 return 的状态。愚蠢的例子在这里:
let hiddenState;
function useState(initialValue) {
if (hiddenState === undefined) {
hiddenState = initialValue;
}
const setState = value => {
hiddenState = value;
}
return [hiddenState, setState];
}
这意味着render
只有在再次调用useState
时才能得到一个新值:
function render() {
let [thing, setThing] = useState(4);
console.log(thing); // 4
setThing(5);
[thing, setThing] = useState(4);
console.log(thing); // 5
}
这本质上就是 useState
所做的,但是隐藏状态在每个实例中都是唯一的。如您所见,setState
被认为是“异步的”,因为状态更改不会反映 直到下一次渲染 。 setState
排队 re-render 请求。下次你的 render 函数被调用时,useState
会被再次调用,它会 return 一个新的值。
注意这些代码修改,而不是我们在更新之前引用状态变量,我们仍然可以引用您的响应对象来获取数据:
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>;
}
发生这种情况是因为当您使用 useState
挂钩时,您正在将状态值 holidayPlans
和 dateArray
分配给局部常量(或变量,这无关紧要),并且每次渲染组件时都会分配这些值。这意味着组件中的常量值不会立即更新,但会反映在下一次渲染中,这将由您在 getHolidayPlans
内执行的状态更新触发。这就是为什么如果您将 console.log()
调用放在 getHolidayPlans
之外,该值会正确打印。
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);
基本上是这样的:
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
重要的是要注意最后 UpcomingHolidays
只是一个函数,它的主体在每个渲染周期执行。
基于此,推荐的方法是使用调用函数 (getHolidayPlans()
) 本地的 constant/variables,而不是在各自的 [= 之后立即使用状态 constant/variables 21=] 函数已被调用,因为它们在调用它的函数完成后更新。
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);
});
};