简体   繁体   中英

Render React component asynchronously (wait for data to be returned)

I have the following ReactJS component :

import React, {useState} from 'react';
import Plot from 'react-plotly.js';

import {utility} from "./utility";

function Chart() {
    
    const [use_data, setData] = useState([]);

    const handleClick = () => {
        const newData = {
            x: ['giraffes', 'orangutans', 'monkeys'],
            y: [20, 14, 23],
            type: 'bar'
        }
        setData((use_data) => [...use_data, newData]);
    };

    return (
        <>
        <button onClick={handleClick}>GO</button>
        <Plot
            var data = {use_data}
            var layout={ {width: 1000, height: 400, title: "Top 100 Topics"} }
        />
        </>
    );

}

export default Chart;

It updates the hardcoded data to produce the following chart on button click:

在此处输入图像描述

Obviously I need to fetch my own data rather than hardcode it as above. In my utilites.js I produce data with the same structure shown above (newData), however it takes about a second to return this data. Thus, React does not render the visual.

ReactJS is obviously looking for some kind of asynchronous state management in order to render this visual (render once data are returned).

const handleClick = () => {
    const newData = utilities.fetch_data()
    setData((use_data) => [...use_data, newData]);
}; 

How can my above code be changed to allow for asynchonous rendering. Is this where a hook is needed to implement something similar to componentDidMount but for functional components?

If I understand the problem correctly, you should use Promise when fetching data, after that, you need a utility to format the response something like the following example:

const formatter = (statics) => {
  const tmp = statics.map((static) => {name: static.name, .......});

  return tmp;
};

function App() {
  const [state, setState] = React.useState(null);

  React.useEffect(() => {
    fetch('https://blahblahblah.com')
      .then((res) => res.json())
      .then((response) => {
        return formatter(response.data.statics);
      })
      .then((formatedData) => setState(formatedData));
  }, []);

  return <h1>{state ? JSON.stringify(state) : "wait..."}</h1>;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM