javascript React组件未使用获取的数据正确更新状态

hs1ihplo  于 2022-12-28  发布在  Java
关注(0)|答案(2)|浏览(130)

我有这两个组件:我获取父组件中的数据,然后将其传递给子组件,子组件将其格式化为一个对象,以便可以在图形的构造中使用它。
第一次安装子组件时,图形不会呈现。如果我尝试更改子组件代码以更新它(例如,从 ForceGraph2D 的props中删除 linkColor),图形将正确显示。我想找到一种方法,在第一次安装组件时立即查看它。

父组件:

import React, {Fragment, useEffect, useState} from "react";
import AddressList from "./AddressList";
import ClusterGraph from "./ClusterGraph";
import axios from "axios";

function ClusterPage(props) {
    const [cluster, setCluster] = useState([]);
    const [subCluster, setSubCluster] = useState([]);

    useEffect(() => {
        fetchData1();
        fetchData2();
    },[]);

    const fetchData1 = async () => {
        const address = props.match.params.addressHash;
        const response = await axios.get('http://localhost:5000/', {
            params: {address: address}
        });
        const data = await response.data;
        setCluster(data);
    }

    const fetchData2 = async () => {
        const address = props.match.params.addressHash;
        const response = await axios.get('http://localhost:5000/sub/', {
            params: {address: address}
        });
        const data = await response.data;
        setSubCluster(data);
    }

    return (
        <div key={props.match.params.id}>
            <Fragment>
                <AddressList data={cluster} />
                <ClusterGraph data1={cluster} data2={subCluster} />
            </Fragment>
        </div>
    );
}

export default ClusterPage;

子组件:

import '../styles/ClusterGraph.css';
import ForceGraph2D from 'react-force-graph-2d';
import React from "react";

class MyClusterGraph extends React.Component {
    constructor(props) {
        super(props);
        this.state = {nodes:[],links:[]};
    }

    componentWillMount() {
        this.loadData();
    }

    loadData = async () => {
        let nodes = this.props.data1.map(row => {
            let id = row.address_id;
            let addressHash = row.address_hash;
            let nodeColor;
            if(row.miner_address)
                nodeColor="blue";
            else
                nodeColor="purple";
            return {id:id,addressHash:addressHash,nodeColor:nodeColor};
        });
        let links = this.props.data2.map(row => {
            let source = row.address_id_1;
            let target = row.address_id_2;
            let linkColor;
            switch (row.link_type) {
                case 0:
                    linkColor="green";
                    break;
                case 1:
                    linkColor="red";
                    break;
                case 2:
                    linkColor="cyan";
                    break;
            }
            return {source:source,target:target,linkColor:linkColor};
        });
        this.setState({nodes:nodes,links:links});
    }

    render() {
        return (
            <div className="graph">
                <ForceGraph2D
                    graphData={this.state}
                    backgroundColor="white"
                    height={400}
                    width={700}
                    nodeLabel="addressHash"
                    nodeColor="nodeColor"
                    linkColor="linkColor" />
            </div>
        );
    }
}

function ClusterGraph({data1,data2}) {
    return (
        <div className="section2">
            <MyClusterGraph data1={data1} data2={data2} />
        </div>
    );
}

export default ClusterGraph;
1qczuiv0

1qczuiv01#

您可以确保在完全获取数据后呈现图形,同时显示加载器,如下所示:

function ClusterPage(props) {
  const [cluster, setCluster] = useState([]);
  const [subCluster, setSubCluster] = useState([]);

  useEffect(() => {
    fetchData1();
    fetchData2();
  }, []);

  const fetchData1 = async () => {
    const address = props.match.params.addressHash;
    const response = await axios.get("http://localhost:5000/", {
      params: { address: address },
    });
    const data = await response.data;
    setCluster(data);
  };

  const fetchData2 = async () => {
    const address = props.match.params.addressHash;
    const response = await axios.get("http://localhost:5000/sub/", {
      params: { address: address },
    });
    const data = await response.data;
    setSubCluster(data);
  };
  if (cluster.length <= 0 || subCluster.length <= 0) {
    return <p>Loading...</p>;
  }
  return (
    <div key={props.match.params.id}>
      <Fragment>
        <AddressList data={cluster} />
        <ClusterGraph data1={cluster} data2={subCluster} />
      </Fragment>
    </div>
  );
}

这样,您将使用constructor来格式化数据,因为componentWillMount()已被弃用并被认为是不安全的:

class MyClusterGraph extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      nodes: this.props.data1.map((row) => {
        let id = row.address_id;
        let addressHash = row.address_hash;
        let nodeColor;
        if (row.miner_address) nodeColor = "blue";
        else nodeColor = "purple";
        return { id: id, addressHash: addressHash, nodeColor: nodeColor };
      }),
      links: this.props.data2.map((row) => {
        let source = row.address_id_1;
        let target = row.address_id_2;
        let linkColor;
        switch (row.link_type) {
          case 0:
            linkColor = "green";
            break;
          case 1:
            linkColor = "red";
            break;
          case 2:
            linkColor = "cyan";
            break;
        }
        return { source: source, target: target, linkColor: linkColor };
      }),
    };
  }

  render() {
    return (
      <div className="graph">
        <ForceGraph2D
          graphData={this.state}
          backgroundColor="white"
          height={400}
          width={700}
          nodeLabel="addressHash"
          nodeColor="nodeColor"
          linkColor="linkColor"
        />
      </div>
    );
  }
}

function ClusterGraph({ data1, data2 }) {
  return (
    <div className="section2">
      <MyClusterGraph data1={data1} data2={data2} />
    </div>
  );
}

export default ClusterGraph;
lhcgjxsq

lhcgjxsq2#

尝试使您的父组件调用同步,当前它是单独同步的,但它以异步方式调用,相应地更改您的代码库

相关问题