在React中处理用户输入以进行API调用
在React中处理用户输入以进行API调用
我只想要通过App.js获取输入的城市名称,并在AirQuality.js中显示从API获取的AQI值。但是它并没有正确地工作。有人可以帮助我吗?我对React API还不熟悉。如果我只是硬编码城市名称,它可以正常工作。
import React from "react"; import "./App.css"; class Airquality extends React.Component { constructor(props) { super(props); this.state = { info: {}, city: {}, parameters: {}, isLoaded: false, }; } getAirquality = (search) => { fetch( "https://api.waqi.info/feed/" + search + "/?token=3c8f71c8438c1b6a06f60477eaf429fe2b61cd3d" ) .then((response) => response.json()) .then((data) => { const newInfo = data.data; const newCity = newInfo.city; const tempData = newInfo.iaqi; const newParameters = tempData.pm25; const loaded = true; const newState = Object.assign({}, this.state, { isLoaded: loaded, info: newInfo, city: newCity, parameters: newParameters, }); this.setState(newState); }); }; componentDidMount() { this.getAirquality(this.props.search); } render() { this.getAirquality(this.props.search); if (!this.state.isLoaded) { return "加载中..."; } else { return (今天{this.state.city.name}的AQI(空气质量指数)是 {this.state.info.aqi}。 PM2.5颗粒物浓度:{this.state.parameters.v}
); } } } class App extends React.Component { constructor(props) { super(props); this.state = { name: "" }; this.handleInput = this.handleInput.bind(this); } handleInput(event) { this.setState({ name: event.target.value, }); } render() { return (); } }
在React中处理用户输入以进行API调用的问题出现的原因是:
1. 使用相同的处理程序`handleInput`和`handleFormSubmit`来处理输入更改和表单提交,这会导致混淆和目的的不同。建议使用不同的处理程序来解决这个问题。
2. 在`
3. 在表单提交处理程序中,使用`event.preventDefault()`来避免重新加载页面。
4. 在渲染过程中不应该调用fetch函数。因为在渲染过程中调用`this.getAirquality(this.props.search)`函数会设置状态,从而再次调用渲染,导致无限循环。相反,应该在类组件中使用`componentDidMount`,或在函数组件中使用`useEffect`。
解决这个问题的方法是:
1. 使用不同的处理程序来处理输入更改和表单提交。
2. 更正`
3. 在表单提交处理程序中使用`event.preventDefault()`。
4. 将fetch函数的调用从渲染过程中移除,改为在`componentDidMount`生命周期方法中调用。
以下是修复后的代码:
import React from "react"; import "./App.css"; class Airquality extends React.Component { constructor(props) { super(props); this.state = { info: {}, city: {}, parameters: {}, isLoaded: false, }; } getAirquality(search) { fetch( "https://api.waqi.info/feed/" + search + "/?token=3c8f71c8438c1b6a06f60477eaf429fe2b61cd3d" ) .then((response) => response.json()) .then((data) => { const newInfo = data.data; const newCity = newInfo.city; const tempData = newInfo.iaqi; const newParameters = tempData.pm25; const loaded = true; const newState = Object.assign({}, this.state, { isLoaded: loaded, info: newInfo, city: newCity, parameters: newParameters, }); this.setState(newState); }); } componentDidMount() { this.getAirquality(this.props.search); } render() { if (!this.state.isLoaded) { return....Loading; } else { return (); } } } class App extends React.Component { constructor(props) { super(props); this.state = { name: "", formSubmit: false }; this.handleInput = this.handleInput.bind(this); this.handleFormSubmit = this.handleFormSubmit.bind(this); } handleInput(event) { console.log(event.target.value); this.setState({ name: event.target.value, }); } handleFormSubmit(event) { event.preventDefault(); console.log(this.state.name); this.setState({ formSubmit: true }); } render() { return (The AQI(Air Quality Index) in {this.state.city.name} is{" "} {this.state.info.aqi} today. Concentration of PM2.5 particle: {this.state.parameters.v}
{this.state.formSubmit &&); } }}
通过上述修复,问题得到了解决。在表单提交后,将会渲染`
React生命周期方法中的`componentDidMount`方法在组件挂载后立即调用,而`componentDidUpdate`方法在组件更新后调用。因此,根据实际需求选择使用哪个方法。
问题的原因是在父组件中使用了错误的状态值来进行API调用,导致在子组件中始终获取到undefined的值。另外,还存在以下问题:
- 在中缺少value={this.state.name},导致输入框处于“半受控”状态,可能会出现奇怪的问题。
- 不应该在render中调用fetch函数,而是应该在class组件中使用componentDidUpdate,在函数组件中使用useEffect。
解决方法是在函数组件中进行如下实现:
import React, { useState, useEffect } from "react"; import "./App.css"; const Airquality = ({ search }) => { const [isLoaded, setIsLoaded] = useState(false); const [info, setInfo] = useState({}); useEffect(() => { setIsLoaded(false); fetch( "https://api.waqi.info/feed/" + search + "/?token=3c8f71c8438c1b6a06f60477eaf429fe2b61cd3d" ) .then((response) => response.json()) .then((response) => { const { data } = response; const { city, aqi } = data; setInfo({ city, pm25: data.iaqi.pm25.v, aqi, data, }); setIsLoaded(true); }); }, [search]); if (!isLoaded) { return....Loading; } const { city, pm25, aqi } = info; return (The AQI(Air Quality Index) in {city} is {aqi} today. Concentration of PM2.5 particle: {pm25}); }; const App = () => { const [name, setName] = useState(""); const handleInput = (e) => { e.preventDefault(); setName(e.target.value); }; return (); }; export default App;
注意:上述代码中仍然存在一些问题。当我输入一个字母时,页面会重新加载并显示关于fetch失败的错误。另外,我尝试将获取到的对象打印到控制台进行检查,但依然出现错误。如果我硬编码城市名称,页面会显示结果,但控制台会持续打印。