无法从main调用类函数,“不是函数”错误

时间:2019-05-14 18:39:57

标签: javascript reactjs

我正在尝试通过创建一个简单的天气应用来学习反应,该应用使用api请求获取数据。 api需要一个可以通过另一个功能获得的位置键。这意味着我必须返回然后将键传递给下一个函数,但是这样做似乎有些麻烦!

TypeError: _LocationKey__WEBPACK_IMPORTED_MODULE_3__.default.setLocation is not a function" is the error i am given when I attempt to run.

我假设我在调用函数的方式以及实际类的结构方面犯了一个错误。任何帮助,将不胜感激!

//The main app
function App() {

  //runs function to set api location key
  new LocationKey();
  LocationKey.setLocation('winnipeg');

  //uses get location key to set weatherData
  new Weather();
  Weather.getWeatherData(LocationKey.getLocation());

  //displays location and weather information 
  return (
    <div className="body">
          <LocationKey/>
          <Weather/>
    </div>
  );
}

//The location key class
export class LocationKey extends Component{

  state = {
    locations: []
  }

  setLocation(name) {
    axios.get('http://dataservice.accuweather.com/locations/v1/cities/search?apikey=oqAor7Al7Fkcj7AudulUkk5WGoySmEu7&q=' + name + '&language=en&details=false')
      .then(res => {
        const locations = res.data;
        this.setState({ locations });
      })
  }

  getLocation(){
      return this.state.locations[0].Key;
  }


  render() {
    return (
      <ul>
        { this.state.locations.slice(0, 1).map(location => <li>{location.EnglishName}</li>)}
      </ul>
    )
  }
}
export default LocationKey

//Weather Class
export class Weather extends Component{

  state = {
    weatherData: []
  }

  //issues command to find weather data from api using location key
  getWeatherData(location) {
    axios.get('http://dataservice.accuweather.com/forecasts/v1/daily/1day/' + location + '?apikey=oqAor7Al7Fkcj7AudulUkk5WGoySmEu7&language=en&details=false&metric=true%20HTTP/1.1')
      .then(res => {
        const weatherData = res.data;
        this.setState({ weatherData });
      })
  }

  render() {
    return (
      <ul>
        { this.state.weatherData.slice(0, 2).map(weather => <li>{weather.Headline.Text}</li>)}
        { this.state.weatherData.slice(0, 2).map(weather => <li>{weather.Headline.Category}</li>)}
        { this.state.weatherData.slice(0, 2).map(weather => <li>{weather.DailyForecasts.Maximum.Value}</li>)}
        { this.state.weatherData.slice(0, 2).map(weather => <li>{weather.DailyForecasts.Minimum.Value}</li>)}
      </ul>
    )
  }
}
export default Weather

1 个答案:

答案 0 :(得分:1)

问题

问题在于此行:

LocationKey.setLocation('winnipeg');

您实例化了LocationKey的新实例,但是看到LocationKey不是单例,而setLocation不是静态方法,则尝试在其中调用实例方法静态方式。

此行的另一个潜在问题是:

Weather.getWeatherData(LocationKey.getLocation());

如上所述,您实例化了Weather的新实例,但是由于它没有执行任何操作且未分配任何内容,因此它立即被丢弃,因此以下行对它。

解决方案

我建议使App成为其自己的组件,并使其包含位置的状态,然后将locations数组传递给每个组件。

class App extends React.Component {

  state = {
    locations: ['winnipeg'],
    locationInput: ''
  };

  render() {
    return ( 
      <div>
        <input value={this.state.locationInput} onChange={e => this.setState({ locationInput: e.target.value })} />
        <button onClick={this.handleAddLocation}>add to locations</button>
        <Weather locations={this.state.locations} />
        <LocationKey locations={this.state.locations} />
      </div>
    )
  }
  
  handleAddLocation = () => {
    if (this.state.locationInput === '') return;
    this.setState({
      locationInput: '',
      locations: [...this.state.locations, this.state.locationInput]
    });
  };
}

class Weather extends React.Component {
  static defaultProps = {
    locations: []
  }

  render () {
    return (
      <div>
        <h2>Weather Component</h2>
        <h3>Locations provided:</h3>
        <span>{this.props.locations.join(', ')}</span>
      </div>
    );
  }
}


class LocationKey extends React.Component {
  static defaultProps = {
    locations: []
  }

  render () {
    return (
      <div>
        <h2>LocationKey Component</h2>
        <h3>Locations provided:</h3>
        <span>{this.props.locations.join(', ')}</span>
      </div>
    );
  }
}

ReactDOM.render( < App / > ,
  document.getElementById('app')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<div id="app"></div>

在以上代码段中,我向您展示了如何使用道具并将其提供给子组件。

我希望这可以帮助并阐明您遇到的一些问题