来自API调用的数据存储在Array中,但是当我尝试在函数中进一步使用该数组时,它表明该数组为空为什么?

问题描述

反应代码,用于将数据从API存储到阵列,并使用相同阵列的event_date值进一步使用。

center

那么,当我使用Same(holidayPlans)数组在html中显示一些内容时,它会显示值并正确显示,但是当我在函数内部使用时,它表明数组内没有数据。

console.log(holidayPlans) shows this

Same Array used to display in html

解决方法

这是一个挑战:编写一个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所能做的就是设置自己的内部状态并更改其返回值。愚蠢的例子在这里:

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使重新渲染请求排队。下次调用渲染函数时,将再次调用useState,它将返回一个新值。

注意这些代码修改,而不是我们在更新状态变量之前先引用状态变量,我们仍然可以引用您的响应对象来获取数据:

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>;
}
,

如果将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);
,

之所以会发生这种情况,是因为使用useState钩子时,您正在将状态值holidayPlansdateArray分配给局部常量(或变量,这无关紧要),以及这些值每次渲染组件时都会分配。这意味着组件中的常量值不会立即更新,而是会在下一个渲染中反映出来,这将由您在getHolidayPlans中进行的状态更新触发。这就是为什么如果将console.log()呼叫放在getHolidayPlans之外,则可以正确打印该值。

export const UpcomingHolidays = (props: UpcomingHolidaysProps) => {
  const [holidayPlans,[]);

  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())本地的常量/变量,而不是在各自的setState函数被使用后立即使用状态常量/变量之所以调用,是因为它们在调用它的功能完成后会更新。

export const UpcomingHolidays = (props: UpcomingHolidaysProps) => {
  const [holidayPlans,[]);

  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);
    });
  };

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...