如何将变量的值从子组件发送到父组件?

时间:2019-02-16 13:41:20

标签: javascript reactjs csv

我需要从CSV文件中加载数据(请参见下面提供的CSVDataTable.js),并将这些数据传递到变量BatchFlights.js中的主要组件this.state.csvData中。然后在this.state.csvData的API请求中使用fetchData()

组件CSVDataTable.js正确加载数据。但是,如何从BatchFlights.js中的handleChange访问它?

BatchFlights.js

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


class BatchFlights extends Component {

  constructor(props) {
      super(props);
      this.state = {
          holdingTime: 1,
          csvData: [],
          delay: 0,
          delay_probability: 0,
          delay_cat: "NA",
          labelWidth: 0
      };
      this.handleChange = this.handleChange.bind(this);
  };

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

  fetchData = () => {
      const url = "http://localhost:8000?"+
        'holdingTime='+this.state.holdingTime+
        '&csvData='+this.state.csvData;

      fetch(url, {
        method: "GET",
        dataType: "JSON",
        headers: {
          "Content-Type": "application/json; charset=utf-8",
        }
      })
      .then((resp) => {
        return resp.json()
      })
      .then((data) => {
        this.updateDelay(data.prediction,data.probability)
      })
      .catch((error) => {
        console.log(error, "catch the hoop")
      })
  };

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

  render() {
    return (

        <Fragment>

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

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

        </Fragment>

    );
  }
}

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

布局/批处理/MainContent.js

import React, { Component, Fragment } from 'react';
import CssBaseline from '@material-ui/core/CssBaseline';
import CSVDataTable from './CSVDataTable';

class MainContent extends Component {
    render() {
        return (
          <Fragment>
              <CssBaseline />
              <main className={this.props.styles.mainPart}>
                  <CSVDataTable />
              </main>
          </Fragment>
        );
    }
}

布局/批处理/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,WAKE,PLANNED_TURNAROUND,SIBT,SOBT,DISTANCE_FROM_ORIGIN,DISTANCE_TO_TARGET
1,M,45,2016-01-01 04:05:00,2016-01-01 14:10:00,2000,2000
`;

class CSVDataTable extends Component {

    state={
      csvData: null
    };

    handleFiles = files => {
        var reader = new FileReader();
        reader.onload =  (e) => {
          // Use reader.result
          this.setState({
            csvData: 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;

更新

  setCsvData = csvData => {
    this.setState({
      csvData
    }, () => {
      console.log("csvData",this.state.csvData)
    });
  }

1 个答案:

答案 0 :(得分:2)

您需要将一个功能从父组件传递给子组件,这将依次设置父组件的状态。

因此,在您的代码中,您必须将一个函数从BatchFlights.js传递给MainContent.js,再传递给CSVDataTable.js。

类似这样的东西:

class BatchFlights extends Component {
// ... class code here.

setCsvData = csvData => this.setState({ csvData })

// ...existing code 

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

然后在MainContent.js中重复相同的过程

<CSVDataTable setCsvData={this.props.setCsvData}/>

然后,您可以在组件中将“ this.props.setCsvData” 与正在加载的响应一起使用。它将在您的父组件中设置状态。