java React + Spring应用程序问题- AxiosError无法获取属性,对象可能已不存在

cqoc49vn  于 2022-12-10  发布在  Java
关注(0)|答案(1)|浏览(104)

我有一个简单的React + Spring应用程序。React部分应该在按下Submit按钮后从前端表单(城市、州、国家)中获取3个参数,将它们传递给后端Spring控制器,获得响应并在同一页面上显示响应的数据值。它可以使用硬编码参数,但更复杂的React逻辑存在问题。

Spring控制器:

@CrossOrigin
@RestController
@RequestMapping("/pollution")
public class PollutionController {
    private static final Logger LOGGER = Logger.getLogger(PollutionController.class.getName());

    JSONObject response;
    private final PollutionService pollutionService;

    PollutionController(PollutionService pollutionService) {
        this.pollutionService = pollutionService;
    }
    
    @GetMapping("/current/city")
    public JSONObject getCurrentPollutionDataByCityStateCountry(
            @RequestParam(value = "city") String city,
            @RequestParam(value = "state") String state,
            @RequestParam(value = "country") String country
    ) {
        try {
            response = pollutionService.getCurrentPollutionDataByCityStateCountry(city, state, country);
        } catch (Exception e) {
            e.printStackTrace();
        }
        LOGGER.log(Level.INFO, "/current/city response: {0}", response);
        return response;
    }

}

响应示例:

{date=Thu Dec 08 01:15:37 CET 2022, no2=27.76, pm2_5=14.12, pm10=19.07}

React应用程序. js部分:

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

import axios from 'axios'

class App extends Component {

    constructor(props) {
        super(props)
        this.state = {
            responseData:'',
            date: '',
            no2: '',
            pm10: '',
            pm2_5: ''
        }

        this.handleClick = this.handleClick.bind(this)
    }

    handleClick () {
        const city = "New York";
        const state = "New York";
        const country = "US";

        axios.get('http://localhost:8080/pollution/current/city?' +
            'city=' + city +
            '&state='+ state +
            '&country=' + country)
            .then(response => this.setState({responseData: response.data}))
        console.log("responseData.date: " + this.state.responseData.date);
    }

    render () {
        return (
            <div className='button__container'>
                <button className='button' onClick={this.handleClick}>Submit</button>
                <p> Date: {this.state.responseData.date}</p>
                <p> no2: {this.state.responseData.no2}</p>
                <p> pm10: {this.state.responseData.pm10}</p>
                <p> pm2_5: {this.state.responseData.pm2_5}</p>
            </div>
        )
    }
}
export default App

它工作正常,我按下提交按钮,从后端得到响应,并在同一网页上看到结果。

但这只是第一个测试阶段。如您所见,所有3个输入参数都是硬编码的。因此,我在App.js文件中添加了一些逻辑,以便从表单中获取参数:

更新的应用程序js

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

import axios from 'axios'

class App extends Component {
    constructor(props) {
        super(props);
        this.state = {
            responseData:'',
            date: '',
            no2: '',
            pm10: '',
            pm2_5: '',
            city: '',
            state: '',
            country: '',
        };

        this.handleClick = this.handleClick.bind(this)
        this.handleInputChange = this.handleInputChange.bind(this);
    }

    handleInputChange(event) {
        const target = event.target;
        const value = target.value;
        const name = target.name;

        this.setState({
            [name]: value
        });
    }

    handleClick() {
    console.log("log record 1");
    console.log("city: " + this.state.city);
        axios.get('http://localhost:8080/pollution/current/city?' +
            'city=' + this.state.city +
            '&state='+ this.state.state +
            '&country=' + this.state.country)
            .then(response => this.setState({responseData: response.data})).catch((err) => console.error(err));

    console.log("response data: " + this.state.responseData);
    console.log("log record 2");
    }

    render() {
        return (
            <form onSubmit={this.handleClick}>
                <label>City:
                    <input name="city" type="text" value={this.state.city} onChange={this.handleInputChange}/>
                </label>
                <br/>
                <label>State:
                    <input name="state" type="text" value={this.state.state} onChange={this.handleInputChange}/>
                </label>
                <br/>
                <label>Country:
                    <input name="country" type="text" value={this.state.country} onChange={this.handleInputChange} />
                </label>
                <br/>
                <input type="submit" value="Submit"/>
                <br/>
                <p> Date: {this.state.responseData.date}</p>
                <p> no2: {this.state.responseData.no2}</p>
                <p> pm10: {this.state.responseData.pm10}</p>
                <p> pm2_5: {this.state.responseData.pm2_5}</p>
            </form>
        );
    }
}
export default App

这里有一个问题-我在表单中输入值,按下Submit,请求将发送到后端部分并生成响应(我可以从后端日志中看到,它将获取参数并生成结果json),但我在同一网页上看不到任何结果
后端响应日志:

INFO 77115 --- [nio-8080-exec-3] c.m.controller.PollutionController       : /current/city response: {"date":"Fri Dec 09 01:11:49 CET 2022","no2":"19.19","pm10":"45.54","pm2_5":"38.07"}

网页上的结果:

那么我的问题是-更新后的App.js中添加的逻辑有什么问题?为什么它不像以前那样呈现响应数据?我在这里错过了什么?
更新日期:

我已经在App.js中添加了一些记录器(上面的代码更新了它们),您可以在控制台中看到下一个结果:

控制台中没有console.log("response data: " + this.state.responseData);的数据,并且在此之后出现2个错误。为什么在我的情况下出现这些错误?

更新2:

我还添加了异常处理(添加到上面的App.js),并在控制台中看到:

bq3bfh9z

bq3bfh9z1#

背景:表单的默认行为是刷新页面,在现代SPA应用程序中,由于许多原因(重置内存中的数据/状态、取消正在进行的请求等),我们试图阻止刷新页面。
解决方案简而言之,只要有表单提交,那么所需的操作就是阻止默认行为。
在您使用ReactJS的情况下,表单提交在
handleClick
方法中处理,解决方案是处理事件并调用preventDefault()。

例如:

handleClick(e) {
  e.preventDefault() // prevent the default behavior
  // The rest of your logic...
}

相关问题