函数在组件更新之前执行

Function executes before component is updated

您可以找到 CodeSandbox here

我是 React 的新手,考虑到 React 中流行的不同代码风格,我发现将我的第一个应用程序放在一起有点混乱。

该应用程序的目的是使用基于表单输入的动态查询来执行 GraphQL 查询。在第一次渲染时,它应该使用状态中提供的数据。当用户更改标准值时,应执行新的 GrapQl。但是,在尝试更改输入值时,只要按下按钮并在(!)更新值之前,就会发布一个新请求。

我尝试了不同的方法,但 none 确实产生了任何变化。

这是我的代码 application

因为我的 GraphQL 服务器是 运行 本地的,你应该期待这个 return:

{
"data": {
    "sensorDataTimeSeriesCurve": [
    {
        "timestamp": "2019-06-12T04:00:00",
        "value": 31.01
    },
    {
        "timestamp": "2019-06-12T05:00:00",
        "value": 33.08
    },
    {
        "timestamp": "2019-06-12T06:00:00",
        "value": 34.28
    }
    ]
}
}

src/index.js

import React, { Component } from "react";
import { render } from "react-dom";

import ApolloClient from "apollo-boost";
import { ApolloProvider, useQuery } from "@apollo/react-hooks";
import gql from "graphql-tag";
import Chart from "./components/charts/chart";

const client = new ApolloClient({
  uri: `https://GRAPHQLENDPOINT`
});

const timeseriesQuery = gql`
  query test0($id1: ID!, $from: DateTime!, $to: DateTime!) {
    sensorDataTimeSeriesCurve(id: $id1, from: $from, to: $to) {
      timestamp
      value
    }
  }
`;

function Timeseries({ id1, from, to }) {
  const { loading, error, data, refetch, networkStatus } = useQuery(
    timeseriesQuery,
    {
      variables: { id1, from, to },
      notifyOnNetworkStatusChange: true
      // pollInterval: 500
    }
  );

  if (networkStatus === 4) return "Refetching!";
  if (loading) return null;
  if (error) return `Error!: ${error}`;
  console.log("Data:", data);

  return (
    <div>
      <Chart data={data.sensorDataTimeSeriesCurve} />
      <button onClick={() => refetch()}>Refetch!</button>
    </div>
  );
}

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      id1: 20742,
      from: "2019-06-12 03:56:13.567",
      to: "2019-06-22 04:56:13.567"
    };
  }
  handleChange = event => {
    let name = event.target.name;
    let value = event.target.value;
    this.setState({ [name]: value });
  };

  render() {
    return (
      <ApolloProvider client={client}>
        <div>
          <form onSubmit={this.handleSubmit}>
            <label>
              Name:
              <input
                type="text"
                value={this.state.id1}
                onChange={this.handleChange}
              />
            </label>
            <label>
              From:
              <input
                type="text"
                value={this.state.from}
                onChange={this.handleChange}
              />
            </label>
            <label>
              To:
              <input
                type="text"
                value={this.state.to}
                onChange={this.handleChange}
              />
            </label>
            <input type="submit" value="Submit" />
          </form>
          {this.state.id1 && (
            <Timeseries
              id1={this.state.id1}
              from={this.state.from}
              to={this.state.to}
            />
          )}
        </div>
      </ApolloProvider>
    );
  }
}

render(<App />, document.getElementById("root"));

src/components/charts/charts.js

import { LineChart, Line } from "recharts";
import React from "react";

class Chart extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      data: this.props.data
    };
  }

  render() {
    return (
      <LineChart width={400} height={400} data={this.state.data}>
        <Line type="monotone" dataKey="value" stroke="#8884d8" />
      </LineChart>
    );
  }
}

export default Chart;

我的预期行为是在按下提交按钮后发出新的 GraphQL 请求。

现在的实际行为是,只要我尝试更改输入字段,就会使用现有输入发出新请求。无法更改输入值。

每当您渲染 Timeseries 组件时都会发送您的查询,并且会立即渲染 Timeseries 组件(您的 App 组件的初始值为真值)。
另一件事是您似乎没有给您的输入实际名称,那么他们应该如何知道要更新哪个值?