函数在组件更新之前执行
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
组件的初始值为真值)。
另一件事是您似乎没有给您的输入实际名称,那么他们应该如何知道要更新哪个值?
您可以找到 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
组件的初始值为真值)。
另一件事是您似乎没有给您的输入实际名称,那么他们应该如何知道要更新哪个值?