Home > Blockchain >  react doesn't render latest value
react doesn't render latest value

Time:09-16

For the initial render, I have object date, which is an empty array. I then try to get data from an influxDB, but the get result isn't reflected by React with a re-render. The get function is calling in useEffect (you can see this in screenshots). I use typescript, and to avoid getting an error on the initial load (that data is an empty array of objects and it doesn't have a value property) I use the typescript syntax, but it still doesn't display the correct value. It doesn't display anything at all.

What could be the problem? In the last photo, we can see another way to display data without a question mark from typescript, but it doesn't work correctly either, even if the length of the array is greater than 0, it still doesn't display data[0].value.

Initial data:
initial data

Data after DB get:
data when function return finally results

Get the first element in array: get the value of the first object in array

Browser result (before ':' we should see data[0].value): results in the browser

Alternate way (when data isn't empty we should see the value of the first object in array): another way

I also show we code

import React from 'react';
import './App.css';
import { FluxTableMetaData } from '@influxdata/influxdb-client';

const { InfluxDB } = require('@influxdata/influxdb-client');

export const App = () => {
  debugger
  const authData = {
    token: 'Emyw1rqUDthYRLpmmBc6O1_yt9rGTT57O50zoKiXUoScAjL6G-MgUN6G_U9THilr86BfIPHMYt6_KSDNHhc9Jg==',
    org: 'testOrg',
    bucket: 'test-bucket',
  };

  const client = new InfluxDB({
    url: 'http://localhost:8086',
    token: authData.token,
  });

  const queryApi = client.getQueryApi(authData.org);
  const query = `from(bucket: "${authData.bucket}") |> range(start: -1d)`;

  const data: any[] = [];
  React.useEffect(() => {
    queryApi.queryRows(query, {
      next(row: string[], tableMeta: FluxTableMetaData) {
        debugger;
        const o = tableMeta.toObject(row);
        const item = {
          time: o._time,
          measurement: o._measurement,
          field: o._field,
          value: o._value,
        };
        return data.push(item);
      },
      error(error: Error) {
        return error;
      },
      complete() {
        console.log(data)
        return data;
      },

    })
  },[]);

  debugger;
  return (
    <div>
      <div>{data.length !== data[0].value}:</div>
      <div>hello</div>
    </div>
  );
};

another way:

<div>
  <div>{data[0]?.value}:</div>
  <div>hello</div>
</div>

CodePudding user response:

I suggest you use the React States for that in the following way

var [nameOfVariableWhichWillChange, changeFunction] = React.useState("");

now whenever whichever function wants to change the value of that function just use changeFunction(newValueOfVariable) the plus point of using React state is wherever you might have used that variable on change of That variable each instance will change on its own... Do let me know does that solve your problem, or you need something else

CodePudding user response:

React doesn't re-render the webpage even if the data has changed. You need to store your data inside a React.useState and call setState to trigger a re-render.

const [data, setData] = useState([])

React.useEffect(() => {
  ...
  next(row: string[], tableMeta: FluxTableMetaData) {
    ...
    setData([...data, item])
  },
...

Read about useState here for more information: https://reactjs.org/docs/hooks-state.html

CodePudding user response:

The main issue in your code is, You have defined data as a const variable, and not as a state. Thus, in useEffect, even if your data gets changed, it will not reflect on data[0].value as it is a const variable and react doesn't render updated values of variables. It updates/renders only if it's a state.

In short, Convert your const data to be a stateand use setState like below for your code to work!

const [data, setData] = React.useState([]);
...
setData([...data , item]);
  • Related