首页 > 解决方案 > React.js 应用程序发送多个 POST 请求而不是单个请求

问题描述

我正在开发向 Django 后端发送请求的 React.js 用户界面。问题是 React.js 应用程序在按钮单击事件和页面重新加载事件上向后端发送多个请求。

Predict但是我想在单击按钮时只发送一个请求BottomControls.js。我的代码有什么问题?

BatchFlights.js

import React, { Component, Fragment } from 'react';
import TopControls from "./layout/batch/TopControls"
import MainContent from "./layout/batch/MainContent"
import BottomControls from "./layout/batch/BottomControls"
import styles from "./layout/styles/styles";
import { withStyles } from "@material-ui/core/styles";

class BatchFlights extends Component {

  constructor(props) {
      super(props);
      this.state = {
          csvData: [],
          holdingTime: 0,
          prediction: 0,
          labelWidth: 0
      };
      this.handleChange = this.handleChange.bind(this);
  };

  componentDidMount() {
      this.fetchData();
  };

  updateDelay(prediction) {
    this.setState(prevState => ({
      prediction: prediction

    }));
  };

  setCsvData = csvData => {
    this.setState({
      csvData
    }, () => {
      console.log(JSON.stringify(csvData))
    });
  }

  fetchData = () => {
      fetch("http://localhost:8000/batch_predict", {
        method: "POST",
        headers: {
          'Accept': 'application/jsonp, text/plain, */*',
            //'Content-Type': 'application/json'
          "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8" // otherwise $_POST is empty
        },
        body: JSON.stringify({
          holdingTime: this.state.holdingTime,
          csvData: this.state.csvData
        })
      })
      .then((resp) => {
        return resp.json()
      })
      .then((data) => {
        this.updateDelay(data.prediction)
      })
      .catch((error) => {
        console.log(error, "catch the hoop")
      })
  };

  handleChange = (name, event) => {
    this.setState({
      [name]: event.target.value
    }, () => {
      console.log("plannedDep",this.state.plannedDep)
    });
  };


  handleReset = () => {
      this.setState({
          prediction: 0
      });
  };

  render() {
    return (

        <Fragment>

            <TopControls state={this.state} styles={this.props.classes} handleChange={this.handleChange} />

            <MainContent state={this.state} styles={this.props.classes} setCsvData={this.setCsvData} />

            <BottomControls state={this.state} styles={this.props.classes} fetchData={this.fetchData} handleReset={this.handleReset}/>

        </Fragment>

    );
  }
}

const StyledBatchFlights = withStyles(styles)(BatchFlights);
export default StyledBatchFlights;

CSVDataTable.js

import React, { Component } from 'react';
import { CsvToHtmlTable } from 'react-csv-to-table';
import ReactFileReader from 'react-file-reader';
import Button from '@material-ui/core/Button';

const sampleData = `
NUM,AIRLINE_ARR_ICAO,WAKE,SIBT,SOBT,PLANNED_TURNAROUND,DISTANCE_FROM_ORIGIN,DISTANCE_TO_TARGET
1,VLG,M,2016-01-01 04:05:00,2016-01-01 14:10:00,45,2000,2000
2,VLG,M,2016-01-01 04:05:00,2016-01-01 14:10:00,45,2000,2000
`;

class CSVDataTable extends Component {

    state={
      csvData: sampleData
    };

    handleFiles = files => {
        var reader = new FileReader();
        reader.onload =  (e) => {
          // Use reader.result
          this.setState({
            csvData: reader.result
          })
          this.props.setCsvData(reader.result)
        }
        reader.readAsText(files[0]);
    }

    render() {
        return <div>
          <ReactFileReader
            multipleFiles={false}
            fileTypes={[".csv"]}
            handleFiles={this.handleFiles}>
            <Button
                variant="contained"
                color="primary"
            >
                Load data
            </Button>

          </ReactFileReader>
          <CsvToHtmlTable
            data={this.state.csvData || sampleData}
            csvDelimiter=","
            tableClassName="table table-striped table-hover"
          />
    </div>
    }
}

export default CSVDataTable;

底部控件.js

import React, { Component, Fragment } from 'react';
import CssBaseline from '@material-ui/core/CssBaseline';
import Grid from '@material-ui/core/Grid';
import Card from '@material-ui/core/Card';
import CardActionArea from '@material-ui/core/CardActionArea';
import CardContent from '@material-ui/core/CardContent';
import AppBar from '@material-ui/core/AppBar';
import Button from '@material-ui/core/Button';
import Icon from '@material-ui/core/Icon';

class BottomControls extends Component {
    render() {
        return (
          <Fragment>
              <CssBaseline />
                <AppBar position="fixed" color="primary" className={this.props.styles.appBar}>
                    <div className={this.props.styles.toolbar}>
                        <Grid container spacing={24}>
                            <Grid item xs={6} sm={3}>
                                <Button variant="contained" color="primary" onClick={this.props.fetchData} className={this.props.styles.button}>
                                    Predict
                                    <Icon className={this.props.styles.rightIcon}>send</Icon>
                                </Button>
                                <Button variant="contained" color="primary" onClick={this.props.handleReset} className={this.props.styles.button}>
                                    Reset
                                    <Icon className={this.props.styles.rightIcon}>clear</Icon>
                                </Button>
                            </Grid>
                            <Grid item xs={6} sm={2}>
                                <Card className={this.props.styles.predictedDelay}>
                                    <CardActionArea>
                                        <CardContent>
                                            <div className={this.props.styles.predictedDelayText}>
                                                Prediction: {this.props.state.prediction} <span> </span>
                                            </div>
                                        </CardContent>
                                    </CardActionArea>
                                </Card>
                            </Grid>
                        </Grid>
                    </div>
              </AppBar>
          </Fragment>
        );
    }
}

export default BottomControls;

标签: javascriptreactjs

解决方案


也许是因为你绑定了一个箭头函数this.handleChange,但除此之外我没有看到任何问题


推荐阅读