首页 > 解决方案 > 无法使用 array.map() 填充选项元素以选择元素

问题描述

我从 api 获取了一组车辆制造,并尝试将数组中的每个项目映射到选择元素中的选项元素:

  const Makes = () => {   
    return (
      <select aria-label="Select a make">
        {/* Populate with option elements based on the years state and its index */}
        <option value="">Select a make</option>
        {makes.map((make) => <option key={make.toString()} value={make}>test</option>)}
      </select>
    );
  };

makes在上层范围内被定义为一个空数组,我用一个fetchMakesByYear看起来像这样的函数填充数组:

  const fetchMakesByYear = async () => {
    const url = `https://www.fueleconomy.gov/ws/rest/vehicle/menu/make?year=${year}`;

    const headers = {
      headers: {
        'Content-Type': 'application/xml',
        Accept: 'application/xml',
      },
    };

    try {
      const data = await fetch(url, headers);
      const itemUnformatted = await data.text();
      const makesByYearUnformatted = convert.xml2js(itemUnformatted, { compact: true, spaces: 2 });
      const makesByYear = makesByYearUnformatted.menuItems.menuItem;

      for (let i = 0; i < makesByYear.length; i += 1) {
        makes.push(makesByYear[i].text._text);
      }
    } catch (err) {
      console.log(err);
    }
  };

  useEffect(() => {
    fetchMakesByYear();
  });

不知道为什么没有填充选项。关于我在这里做错了什么的任何想法?谢谢。

标签: javascriptarraysreactjsjsx

解决方案


使用 state 来存储makes数组并在 fetch 时更新它,这将重新渲染您的组件并useEffect调用您fetchMakesByYear的组件安装。

无限渲染是因为你没有传入依赖数组useEffect,所以每次渲染都会调用它。

const [makes,setMakes] = useState([]) // use state to hold your array

const fetchMakesByYear = useCallback(async () => { // use useCallback hook to wrap your function so that this function is not created on every render and hence doesn't call useEffect as we will be giving it as a dependency
    const url = `https://www.fueleconomy.gov/ws/rest/vehicle/menu/make?year=${year}`;

    const headers = {
      headers: {
        'Content-Type': 'application/xml',
        Accept: 'application/xml',
      },
    };

    try {
      const data = await fetch(url, headers);
      const itemUnformatted = await data.text();
      const makesByYearUnformatted = convert.xml2js(itemUnformatted, { compact: true, spaces: 2 });
      const makesByYear = makesByYearUnformatted.menuItems.menuItem;

      for (let i = 0; i < makesByYear.length; i += 1) {
        makes.push(makesByYear[i].text._text);
      }
      setMakes(makes) // set state to update your array in the state
    } catch (err) {
      console.log(err);
    }
},[]);

useEffect(()=>{
  fetchMakesByYear()
},[fetchMakesByYear]) // add dependency in useEffect here

return (
   {Makes()}
}


推荐阅读