开发者问题收集

检查了无数次,还是找不到我的错误在哪里:Uncaught TypeError: Cannot read properties of undefined (reading 'lat')

2022-12-06
132

我一直在玩OpenWeatherMap API,以学习编码,并遇到了我的控制台中弹出的一系列TypeError问题。我的假设是我的程序正在尝试在API完成之前使用数据,但是我将提取功能设置为等待,直到收到响应将其添加到相应的状态,并尝试了许多解决方案。我在下面包含了我的app.js代码(随附的API密钥):

297475494

附加上下文:apidata state作为Props传递给儿童组件,并用于呈现数据屏幕上存储在Apidata中的数据。

,控制台中有多个错误,就像我在问题标题中包含的一个错误一样,可能都是源于同一问题。

在过去的三个小时中一直无法弄清楚这一点。所有和所有协助都非常感谢。

3个回答

也许可以尝试以下步骤来生成正确的 URL 且不出现错误:

  1. inputData 提供具有正确数据模型的初始值
  2. inputData 未准备好时,为 url 提供后备值

以下实时示例将使用公共 API,因此不需要密钥,如果切换到项目 API,它也应该可以工作。

示例:(在 codesandbox 上进行了简化的实时演示)

inputData 需要正确的数据模型,以便 url 读取其属性:

// GeoCoder API data to feed into the main weather API
const [inputData, setInputData] = useState({ lat: null, lon: null });

urlinputData 已获取但尚未准备好时需要一个后备值(这里使用了 null ,但它可以是任何值,具体取决于如何使用它):

// Main weather API used for feeding data to the UI (based on lat & lon from geoCoder API)
const url =
  inputData?.lat && inputData?.lon
    ? `https://api.openweathermap.org/data/2.5/weather?lat=${inputData.lat}&lon=${inputData.lon}&appid=API__KEY&units=imperial`
    : null;

可选:可以在 useEffect 内部创建数据获取函数,因此不需要将其添加到依赖项数组中。

// Initialize website with data
useEffect(() => {
  const initInputData = async () => {
    if (!geoCoder) return;
    const res = await fetch(geoCoder);
    if (!res.ok) throw new Error("fetch failed");
    const jsonRes = await res.json();
    setInputData(jsonRes);
  };
  initInputData().catch((error) => console.error(error));
}, [geoCoder]);

可能还有其他问题需要解决,但希望这至少可以帮助生成正确的 URL 而不会出现错误。

John Li
2022-12-06

始终为状态变量设置 初始值

const [inputData, setInputData] = useState({ lat: null, lon: null });
const [apiData, setApiData] = useState({})
Ken Labso
2022-12-06

更新:这里的解决方案非常简单,我觉得自己像个白痴,没有早点注意到它。评论是正确的,因为我需要一个后备方案。我设置了利用获取的数据的组件,当所需状态属性为真时,这些组件将有条件地呈现。为了简单起见,我在核心文档上更改了一些内容,但解决方案仍然适用于这两种情况。如果 apiData.main 和 ForecastData.list(这是在发布初始问题后创建的)都是真值,则使用获取的项目呈现组件,否则,呈现一个空字符串。

{apiData.main && forecastData.list ? (
    <>
      <Pinpoint apiData={apiData} />
      <ForecastPreview apiData={apiData} />
      <ForecastDetails
        apiData={apiData}
        forecastData={forecastData}
        getForecastData={getForecastData}
      />
    </>
  ) : (
    ""
  )}
Brian
2023-01-04