来自 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 挂钩时,您正在将状态值 holidayPlansdateArray 分配给局部常量(或变量,这无关紧要),并且每次渲染组件时都会分配这些值。这意味着组件中的常量值不会立即更新,但会反映在下一次渲染中,这将由您在 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);
    });
  };