将 props 传递给 axios get 请求

时间:2021-06-14 12:58:27

标签: reactjs axios react-props

我的目的是获取所选国家的天气数据,将 selectedCountry.capital 传递给查询,所以当显示一个国家的数据时,它会显示当前国家首都的天气。

useEffect(() => {

  axios
    .get(
      `http://api.weatherstack.com/current?access_key=b51dfd70b0b2ccf136a0d7352876661c&query=${selectedCountry.capital}`
    )
    .then(res =>{
      console.log(res.data)
      console.log("capital"+selectedCountry.capital)
      setWeather(res.data.current)
    } )

}, [])

第一个问题:我没有将 selectedCountry.capital 传递给查询,因为 console.log("capital"+selectedCountry.capital) 返回 undefined。

如果我对查询进行硬编码,我会得到天气响应。

useEffect(() => {

  axios
    .get(
      `http://api.weatherstack.com/current?access_key=b51dfd70b0b2ccf136a0d7352876661c&query=New York`
    )
    .then(res =>{
      console.log(res.data)
      console.log("capital"+selectedCountry.capital)
      setWeather(res.data.current)
    } )

}, [])

我也试过这样传

useEffect(() => {

  axios
    .get(
      `http://api.weatherstack.com/current?access_key=b51dfd70b0b2ccf136a0d7352876661c&query=New York`
    )
    .then(res =>{
      console.log(res.data)
      console.log("capital"+selectedCountry.capital)
      setWeather(res.data.current)
    } )

}, [selectedCountry.capital])

[selectedCountry.capital]) 我可以登录首都。但这是一种奇怪的方法。而且我无法显示天气数据,因为只有在我选择国家/地区后它才会通过 selectedCountry.capital 。应该还有别的办法。

如何将 selectedCountry.capital 传递给天气查询?

完整代码: code sandbox

import React, { useState, useEffect } from 'react'
import axios from 'axios'
//setCountries is a function for setting the country's state
const App = () => {
  const [countries, setCountries] = useState([])
//Filter
const [searchFilter, setSearchFilter] = useState('')

//Update state with button
const [selectedCountry, setSelectedCountry] = useState('')

const [weather, setWeather] = useState('')
  
const hook = () => {
    console.log('effect')
    axios
      .get('https://restcountries.eu/rest/v2/all')
      .then(response => {
        console.log('promise fulfilled')
        setCountries(response.data)
        
      })
  }

  useEffect(hook,[])
/*   by default the effect is always run after the component has been rendered. In our case, however, we only want to execute the effect along with the first render.
  The second parameter of useEffect is used to specify how often the effect is run. If the second parameter is an empty array [], then the effect is only run along with the first render of the component. */

  console.log('render', countries.length, 'countries')
  console.log(countries)

/* weather */

useEffect(() => {
  if( selectedCountry.capital !== '' )
  {
    axios
    .get(
      `http://api.weatherstack.com/current?access_key=b51dfd70b0b2ccf136a0d7352876661c&query=${selectedCountry.capital}`
    )
    .then(res =>{
      console.log(res.data)
      console.log("capital" +selectedCountry.capital)
      setWeather(res.data.current)
      
    } )
  }    
}, [selectedCountry.capital])





  //When button es clicked the state is set, and the state variable is used

  const renderCountryDetails = () => {
    return (
      selectedCountry && (
        <p key={selectedCountry.alpha2Code}>
       <p>   Capital: {selectedCountry.capital}.</p>
       <p>  Population:{" "}
          {selectedCountry.population}</p> 

          <p>
            <img src={selectedCountry.flag} style={{ width: '200px'}}/>
</p> 
        
<h3>Languages</h3>
<p>      {selectedCountry.languages.map(language => <li key={language.name}>{language.name}</li>)}

   <div>
          <h4>Weather</h4>
          <h5>temperature: {weather.temperature} Celisues</h5>
          <img src={weather.weather_icons[0]} alt='' />
          <h5>
            wind: {weather.wind_degree} mph direction {weather.wind_dir}
          </h5>
        </div>   

</p>



</p>


      )
    );
  };



const filteredCountries =
searchFilter.length === 1
? countries
: countries.filter(
(country) => country.name.toLowerCase().indexOf(searchFilter.toLowerCase()) > -1
)

//showCountries returns either a message or else the contents of filteredcountries array
const showCountries = () => {


if (filteredCountries.length > 10) {
return 'Too many matches, keep on typing'
}


if (filteredCountries.length > 0 
    && filteredCountries.length<10 
    && filteredCountries.length>1 ) 
    {
      return (
        <div>
          {filteredCountries.map((country) => (
            <p key={country.alpha2Code}>
              {country.name}
              {
                //Update stste when button is clicked, passing country as a prop to the state
                //onClick state is updated, causing the page to refresh and executing renderCountryDetails
                //that uses the set state (the country) to render the info.
                <button onClick={
                  () => setSelectedCountry(country)}>
                  show
                </button>
              }
            </p>
          ))}
          <div>{renderCountryDetails()}</div>
          <div>
            <p></p>
        </div>
        </div>
      );
    }
    
    

    if (filteredCountries.length === 1) {
      return filteredCountries.map((country) =>

      
  <p key={country.alpha2Code}>
    <p>Capital: {country.capital}.
    <p> Population: {country.population} </p> 
    <h3>languages</h3>
                {country.languages.map(language => <li key={language.name}>{language.name}</li>)}

    <p><img src={country.flag} style={{ width: '200px'}}/>
    </p> 
    
    </p>
    </p>

  )
      }
    } 
     


const searchHandler = (e) => {
  //setSelectedCountry state is set to empty
  setSelectedCountry("");
setSearchFilter(e.target.value)
}

  return (
<div>

<div>
<h1>Countries</h1>
</div>
<div>
Type to find countries: 
<input onChange={searchHandler} />
<div>
{showCountries()}
</div>
</div>

</div>
  );
}


export default App;

编辑: 我得到了通过 selectedCountry.capital 的数组数据,就像这样


useEffect(() => {
  if( selectedCountry.capital !== '' )
  {
    axios
    .get(
      `http://api.weatherstack.com/current?access_key=b51dfd70b0b2ccf136a0d7352876661c&query=${selectedCountry.capital}`
    )
    .then(res =>{
      console.log(res.data)
      console.log("capital" +selectedCountry.capital)
      setWeather(res.data.current)
      
    } )
  }    
}, [selectedCountry.capital])

但是,我无法在获取数组后访问该数组,从而导致错误。

<块引用>

类型错误:无法读取未定义的属性“温度” 代码更新

1 个答案:

答案 0 :(得分:1)

问题在这里:

useEffect(() => {

}, []);

useEffect 将在组件加载时运行,此时 ${selectedCountry.capital} 为空白。

要处理此问题,请尝试以下操作:

useEffect(() => {
  if( selectedCountry.capital} !== '' )
  {
    // Make your axios call here
  }    
}, [selectedCountry.capital]);  

selectedCountry.capital 是依赖项,因此此效果将在组件加载时运行,每次 selectedCountry.capital 都会更改,并且在此效果第一次运行时,我们会进行条件检查,因此不会触发 axios 请求。

相关问题