函数在组件更新之前执行

Posted

技术标签:

【中文标题】函数在组件更新之前执行【英文标题】:Function executes before component is updated 【发布时间】:2019-12-28 15:27:54 【问题描述】:

您可以找到CodeSandbox here

我对 react 很陌生,考虑到不同代码风格在 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】:

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

【讨论】:

我明白了。看来我的表格设置不正确。我错误地认为它有不同的原因。我会尝试解决这个问题。谢谢@Dor Shinar。 你当然是对的,我假设 react 会自动检索键值关系,但我当然需要指定 name 属性。该代码现在有效。感谢上帝,已经是星期五了。现在我只需要弄清楚如何确保请求仅在按下提交后运行。

以上是关于函数在组件更新之前执行的主要内容,如果未能解决你的问题,请参考以下文章

Vue——生命周期和钩子函数的一些理解

React教程:组件的生命周期

路由器事件在构造函数上使用时会导致错误警告:无法对未安装的组件执行 React 状态更新

Vue-的父组件和子组件生命周期钩子函数执行顺序

组件的生命周期

反应钩子。无法对未安装的组件执行 React 状态更新