函数在组件更新之前执行

时间:2019-08-23 10:05:06

标签: reactjs graphql apollo react-apollo react-apollo-hooks

您可以找到CodeSandbox here

我是一个非常新的响应者,鉴于React中存在各种不同的代码样式,我发现将我的第一个应用程序放在一起有点令人困惑。

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

我尝试了不同的方法,但是没有任何改变。

这是我的代码,application

由于我的GraphQL服务器在本地运行,因此您应该期望得到以下回报:

{
"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请求。

现在的实际行为是,一旦我尝试更改输入字段,就会使用现有输入发出新请求。不能更改输入值。

1 个答案:

答案 0 :(得分:1)

只要渲染Timeseries组件,就立即发送查询,而Timeseries组件则立即渲染(App组件的初始值是真实的)。
另一件事是您似乎没有给输入实际名称,因此他们应该如何知道更新哪个值?