Javascript TypeError:无法读取属性';条件';未定义的

Javascript TypeError:无法读取属性';条件';未定义的,javascript,reactjs,npm,Javascript,Reactjs,Npm,所以我试着学习React,但我在尝试做天气应用时遇到了麻烦 这些是我的组件和app.js文件 从“React”导入React 常量天气卡=(道具)=>{ 返回( {props.location} {props.条件}{props.温度}摄氏度 ) } 导出默认天气预报卡 import'/App.css'; 从“React”导入React,{useffect,useState}; 从“./components/WeatherCard”导入WeatherCard; 常量应用=()=>{ const

所以我试着学习React,但我在尝试做天气应用时遇到了麻烦

这些是我的组件和app.js文件

从“React”导入React
常量天气卡=(道具)=>{
返回(

{props.location}

{props.条件}{props.温度}摄氏度 ) } 导出默认天气预报卡
import'/App.css';
从“React”导入React,{useffect,useState};
从“./components/WeatherCard”导入WeatherCard;
常量应用=()=>{
const APP_KEY=“我的钥匙(是的,我把钥匙放在这里)”;
const[weatherDatas,setWeather]=useState({});
const[search,setSearch]=useState(“”);
const[query,setQuery]=useState('Iglesias');
useffect(()=>{
getWeather();
},[查询];
const getWeather=async()=>{
const response=等待获取(`http://api.weatherapi.com/v1/current.json?key=${APP_KEY}&q=${query}`);
const data=wait response.json()
天气(数据);
}
const updateSearch=e=>{
设置搜索(如目标值);
}
const getSearch=e=>{
e、 预防默认值();
设置查询(搜索);
}
返回(
搜寻
)
}

导出默认应用程序这是一个典型错误,因为您正在运行一个异步函数,当您的组件装载时,收到的道具只是“{}”,这就是您收到错误的原因。我更改了你的代码片段,我想现在它可以工作了

import './App.css';
import React, {useEffect, useState} from 'react';
import WeatherCard from './components/WeatherCard';


const App = () => {
  const APP_KEY = "My_key(yes, I put my key here)";
  const [weatherDatas, setWeather] = useState(null); //CHANGE HERE
  const [search, setSearch] = useState(""); 
  const [query, setQuery] = useState('Iglesias');

  useEffect(() => {
    getWeather();
  },[query]);

  const getWeather = async () => {
    const response = await fetch(`http://api.weatherapi.com/v1/current.json?key=${APP_KEY}&q=${query}`);
    const data = await response.json()
    setWeather(data);
  }

  const updateSearch = e => {
    setSearch(e.target.value);
  }

  const getSearch = e => {
    e.preventDefault();
    setQuery(search);
  }

  return(
    <div className="App">
      <form onSubmit={getSearch} className="SearchForm d-flex justify-content-center">
        <input type='text' value = {search} onChange = {updateSearch} />
        <button type='submit'>Search</button>
      </form>
      <div className='d-flex justify-content-center'>
        {weatherDatas && ( //CHANGE HERE
          <WeatherCard 
          icon = {weatherDatas.current.condition.icon}
          location = {weatherDatas.location.name}
          condition = {weatherDatas.current.condition.text}
          temperature = {weatherDatas.current.temp_c}
        />)}
      </div>
      
    </div>
  )
}

export default App;
import'/App.css';
从“React”导入React,{useffect,useState};
从“./components/WeatherCard”导入WeatherCard;
常量应用=()=>{
const APP_KEY=“我的钥匙(是的,我把钥匙放在这里)”;
const[weatherDatas,setWeather]=useState(null);//在此处更改
const[search,setSearch]=useState(“”);
const[query,setQuery]=useState('Iglesias');
useffect(()=>{
getWeather();
},[查询];
const getWeather=async()=>{
const response=等待获取(`http://api.weatherapi.com/v1/current.json?key=${APP_KEY}&q=${query}`);
const data=wait response.json()
天气(数据);
}
const updateSearch=e=>{
设置搜索(如目标值);
}
const getSearch=e=>{
e、 预防默认值();
设置查询(搜索);
}
返回(
搜寻
{weatherDatas&&(//在此处更改
)}
)
}
导出默认应用程序;

现在,您的代码将尝试呈现组件,当它加载时,这是一个典型错误,因为您正在运行一个异步函数,当您的组件装载时,收到的道具只是“{}”,这就是您收到错误的原因。我更改了你的代码片段,我想现在它可以工作了

import './App.css';
import React, {useEffect, useState} from 'react';
import WeatherCard from './components/WeatherCard';


const App = () => {
  const APP_KEY = "My_key(yes, I put my key here)";
  const [weatherDatas, setWeather] = useState(null); //CHANGE HERE
  const [search, setSearch] = useState(""); 
  const [query, setQuery] = useState('Iglesias');

  useEffect(() => {
    getWeather();
  },[query]);

  const getWeather = async () => {
    const response = await fetch(`http://api.weatherapi.com/v1/current.json?key=${APP_KEY}&q=${query}`);
    const data = await response.json()
    setWeather(data);
  }

  const updateSearch = e => {
    setSearch(e.target.value);
  }

  const getSearch = e => {
    e.preventDefault();
    setQuery(search);
  }

  return(
    <div className="App">
      <form onSubmit={getSearch} className="SearchForm d-flex justify-content-center">
        <input type='text' value = {search} onChange = {updateSearch} />
        <button type='submit'>Search</button>
      </form>
      <div className='d-flex justify-content-center'>
        {weatherDatas && ( //CHANGE HERE
          <WeatherCard 
          icon = {weatherDatas.current.condition.icon}
          location = {weatherDatas.location.name}
          condition = {weatherDatas.current.condition.text}
          temperature = {weatherDatas.current.temp_c}
        />)}
      </div>
      
    </div>
  )
}

export default App;
import'/App.css';
从“React”导入React,{useffect,useState};
从“./components/WeatherCard”导入WeatherCard;
常量应用=()=>{
const APP_KEY=“我的钥匙(是的,我把钥匙放在这里)”;
const[weatherDatas,setWeather]=useState(null);//在此处更改
const[search,setSearch]=useState(“”);
const[query,setQuery]=useState('Iglesias');
useffect(()=>{
getWeather();
},[查询];
const getWeather=async()=>{
const response=等待获取(`http://api.weatherapi.com/v1/current.json?key=${APP_KEY}&q=${query}`);
const data=wait response.json()
天气(数据);
}
const updateSearch=e=>{
设置搜索(如目标值);
}
const getSearch=e=>{
e、 预防默认值();
设置查询(搜索);
}
返回(
搜寻
{weatherDatas&&(//在此处更改
)}
)
}
导出默认应用程序;

现在,您的代码将尝试渲染组件,当加载组件时,这是由线程引起的常见问题。您的变量没有赋值,因此为空,并且您无法从变量中提取某些内容,因此它会抛出“无法读取未定义的属性'xxxx'错误”

我可以理解为什么由于“wait”关键字,您认为应该填充
weatherDatas
变量,但是在“async”方法中嵌入了该变量。在这种情况下,“异步”胜过“等待”

使用
weatherDatas
变量时,需要执行空检查。您应该查看,这意味着您将在
前面用问号调用对象,以便它在尝试使用数据之前验证数据是否存在

有两种方法可以做到这一点,它们的效果好坏取决于你的预期。以下是一些示例,但它们不一定是您想要的:

icon = {weatherDatas?.current?.condition?.icon}
location = {weatherDatas?.location.name}
condition = {weatherDatas.current.condition?.text}
图标
变量的示例可能是您想要的。它防止
图标
被分配超出
null
的任何内容,除非整个对象路径有数据,因此它不会在尝试访问
天气数据
当前
条件
时抛出空引用错误。但是,如果
weatherDatas.current.condition.icon
为空,则
图标仍然可以为空。这可能是您想要的情况,因为它会在访问对象的属性之前检查所有对象是否为null。这可能不是每个对象使用都需要的,但对于单个使用或您已有的使用来说都很好。不过,进行常规的空检查通常会更好

对于
location
变量,它不会在尝试访问
weatherDatas
时抛出null引用错误,但如果它为null,则可以在访问
weatherDatas.location
时抛出null引用错误

条件
变量示例中,您仍然可以在
天气数据
当前
上获得空参考错误,但不能在
条件
上获得空参考错误。由于您的
weatherDatas
为空,因此在当前设置中仍然会失败,因此这不是您现在想要的