React - 在组件

时间:2017-09-07 08:21:56

标签: javascript reactjs dom components

这是我在一个简单的React应用程序中的第一次尝试。使用Openweather API和AXIOS。我选择了Stephen Grider的Udemy课程,我现在正试图自己创建一些东西,但是在组件之间传递数据时仍然存在问题。我有一个SearchBar组件,我希望能够将输入值传递给父组件的状态,因此我可以在每次搜索时更新它并将其呈现到DOM中。但是,我一直遇到错误。我尝试将一个函数作为prop传递给我的SearchBar组件但是我收到了错误:

  

setState(...):只能更新已安装或安装的组件。这通常意味着您在已卸载的组件上调用了setState()。这是一个无操作。请检查应用程序组件的代码。

     

未定义citySearch

这让我感到困惑,因为我试图从课程中复制确切的步骤,似乎工作得很好。但同样,我对此非常陌生,所以可能只是我犯了一些新手的错误。任何提示都将非常感激。

检查下面的代码:

App.js

import React, { Component } from 'react';
import './App.css';

//Libraries
import axios from 'axios';

//Components
import SearchBar from './Components/search-bar';
class App extends Component {
  constructor(props){
    super(props);

    this.state = {
      city: 'London',
      country: 'uk',
      temperature: 0,
      humidity: 0,
      pressure: 0
    }

    //Axios call
    let city = this.state.city;
    let country = this.state.country;
    axios
      .get(`http://api.openweathermap.org/data/2.5/weather?APPID=${API_KEY}&q=${city},${country}`)
      .then(function(response) {
        this.setState({
          city: response.data.name,
          country: response.data.name,
          temperature: response.data.main.temp,
          humidity: response.data.main.humidity,
          pressure: response.data.main.pressure
        });
      }.bind(this))
      .catch(function(error) {
        console.log(error);
      });

      this.citySearch('London');
  }

  citySearch(city){
    this.setState({city})
  }

  render() {
    return (
      <div className="container">
        <h1 className="display-1 text-center">Weather App</h1>
        <SearchBar onSearchTermChange={citySearch} />
      </div>
    );
  }
}

export default App;

SearchBar组件:

import React, { Component } from 'react';

class SearchBar extends Component {
  constructor(props) {
    super(props);

    this.state = {
      city: ""
    };
  }

  render() {
    return (
      <input
        value={this.state.city}
        onChange={this.onHandleChange}
        className="form-control mt-3"
        placeholder="Enter a city name..."
        type="text"
      />
    );
  }

  onHandleChange(city) {
    this.setState({ city });
    this.props.onSearchTermChange(city);
  }
}

export default SearchBar;

4 个答案:

答案 0 :(得分:0)

你只需要在构造函数中设置state。如果您想拨打电话,可以将其放在componentWillMount()componentDidMount()

import React, { Component } from 'react';
import './App.css';

//Libraries
import axios from 'axios';

//Components
import SearchBar from './Components/search-bar';
class App extends Component {
  constructor(props){
    super(props);

    this.state = {
      city: 'London',
      country: 'uk',
      temperature: 0,
      humidity: 0,
      pressure: 0
    }
  }

  citySearch(city){
    this.setState({city})
  }

  componentWillMount(){
    //Axios call
    let city = this.state.city;
    let country = this.state.country;
    axios
      .get(`http://api.openweathermap.org/data/2.5/weather?APPID=${API_KEY}&q=${city},${country}`)
      .then(function(response) {
        this.setState({
          city: response.data.name,
          country: response.data.name,
          temperature: response.data.main.temp,
          humidity: response.data.main.humidity,
          pressure: response.data.main.pressure
        });
      }.bind(this))
      .catch(function(error) {
        console.log(error);
      });

      this.citySearch('London');
  }

  render() {
    return (
      <div className="container">
        <h1 className="display-1 text-center">Weather App</h1>
        <SearchBar onSearchTermChange={citySearch} />
      </div>
    );
  }
}

export default App;

答案 1 :(得分:0)

  

setState(...):只能更新已安装或安装的组件。这个   通常意味着您在未安装的组件上调用了setState()。这是   无操作。请检查应用程序组件的代码。

这是因为您在构造函数中进行了 Dim files() As String = Directory.GetFiles(txt_folder.Text) For Each a In CStr(files.Count) folder_hard.Rows.Add(Directory.GetFiles(txt_folder.Text)) Next 调用。将你的axios电话放入axios解决它

  

未定义citySearch

这是因为React找不到componentDidMount函数。你应该改变

citySearch

<SearchBar onSearchTermChange={citySearch} />

为了以这种方式使用<SearchBar onSearchTermChange={this.citySearch} />,您还应该在构造函数中绑定citySearch

总结:

citySearch

不要在你的构造函数中调用import React, { Component } from 'react'; import './App.css'; //Libraries import axios from 'axios'; //Components import SearchBar from './Components/search-bar'; class App extends Component { constructor(props){ super(props); this.state = { city: 'London', country: 'uk', temperature: 0, humidity: 0, pressure: 0 } this.citySearch = this.citySearch.bind(this) } componentDidMount() { //Axios call let city = this.state.city; let country = this.state.country; axios .get(`http://api.openweathermap.org/data/2.5/weather?APPID=${API_KEY}&q=${city},${country}`) .then(function(response) { this.setState({ city: response.data.name, country: response.data.name, temperature: response.data.main.temp, humidity: response.data.main.humidity, pressure: response.data.main.pressure }); }.bind(this)) .catch(function(error) { console.log(error); }); } citySearch(city){ this.setState({city}) } render() { return ( <div className="container"> <h1 className="display-1 text-center">Weather App</h1> <SearchBar onSearchTermChange={this.citySearch} /> </div> ); } } export default App;,你可以像你的那样初始化你的状态。因此,应删除构造函数中的原始setState

更新

每次拨打setState时都要再次搜索。

citySearch

答案 2 :(得分:0)

首先,你不应该在构造函数中进行axios调用。此时尚未安装该组件。在componentDidMount中执行此操作以确保已装入组件。

顺便说一句,您没有将citySearch绑定到App类。所以在SearchBar组件中,它不知道应该从App类调用citySearch方法。出于优化原因,建议在App类构造函数中执行此绑定。

最后,我建议您利用状态管理框架(如ReduxFlux

以更具功能性的方式编写React

以下代码应该有效

import React, { Component } from 'react';
import './App.css';

//Libraries
import axios from 'axios';

//Components
import SearchBar from './Components/search-bar';
class App extends Component {
  constructor(props){
    super(props);

    this.state = {
      city: 'London',
      country: 'uk',
      temperature: 0,
      humidity: 0,
      pressure: 0
    }
    this.citySearch = this.citySearch.bind(this);
    this.citySearch('London');
  }

  citySearch(city){
    this.setState({city})
  }

  componentDidMount() {
    //Axios call
    let {city, country} = this.state;
    axios
      .get(`http://api.openweathermap.org/data/2.5/weather?APPID=${API_KEY}&q=${city},${country}`)
      .then(function(response) {
        this.setState({
          city: response.data.name,
          country: response.data.name,
          temperature: response.data.main.temp,
          humidity: response.data.main.humidity,
          pressure: response.data.main.pressure
        });
      }.bind(this))
      .catch(function(error) {
        console.log(error);
      });
  }

  render() {
    return (
      <div className="container">
        <h1 className="display-1 text-center">Weather App</h1>
        <SearchBar onSearchTermChange={citySearch} />
      </div>
    );
  }
}

export default App;

对于searchBar组件,您没有在SearchBar组件中绑定onHandleChange。这会抛出错误。您应该在searchBar构造函数

中执行此操作
constructor() {
     ...
     this.onHandleChange = this.onHandleChange.bind(this) //Very important you do this
  }

答案 3 :(得分:0)

要将数据从子组件传递到父组件,您必须使用回调方法。

检查一下。 (关于如何将数据从父级传递到子级以及子级传递到父级)。

我知道我不是在这里触摸您的代码的(很抱歉),但是如果您对其他方法感兴趣,那么可以这样做。

https://medium.com/@ruthmpardee/passing-data-between-react-components-103ad82ebd17