代码之家  ›  专栏  ›  技术社区  ›  Samra

无限API调用回调中更改状态

  •  0
  • Samra  · 技术社区  · 3 年前

    我正在尝试将数据从API加载到树视图(material-UI)。如果数据是静态的,那么一切都很好,但如果我在回调中使用API,它会触发无限制的调用。。。

    const getTreeItemsFromData = (treeItems) => {
      //e.stoppropagation();
      return treeItems.map((treeItemData) => {
        let children = undefined;
        if (treeItemData.children && treeItemData.children.length > 0) {
          children = getTreeItemsFromData(treeItemData.children);
        }
        return (
          <TreeItem
            key={treeItemData.id}
            nodeId={treeItemData.id}
            label={treeItemData.name}
            children={children}
          />
        );
      });
    };
    
    export default function UpdateFieldObservations({
      formdata,
      handleChangeParent
    }) {
      const [matrixData, setMarixData] = useState([]);
    
      const airdata = [
        {
          id: 1,
          name: "Soil Vapour",
          children: [
            {
              id: 11,
              name: "Grab Sample"
            },
            {
              id: 12,
              name: "Insitu Meter Reading"
            }
          ]
        }
      ];
    
      console.log("Call API with matrixId : " + form.matrixId);
      axiosInstance
        .get("/observations/" + form.matrixId, {
          headers: { "Content-Type": "application/json" }
        })
        .then((res) => {
          console.log(res);
        })
        .catch((err) => {
          console.log("Error: " + err);
        });
    
      return (
        <>
          <TreeView
            className={classes.root}
            defaultCollapseIcon={<ExpandMoreIcon />}
            defaultExpandIcon={<ChevronRightIcon />}
            onNodeSelect={handleNodeSelected}
          >
            {getTreeItemsFromData(airdata)}
          </TreeView>
        </>
      );
    }
    

    现在,如果我在下面加上

    console.log(res)

    setMarixData(res);

    它从无限制的API调用开始。。我做错了什么,以及如何最好地将这些数据加载到树中,而不是 空中数据

    1 回复  |  直到 3 年前
        1
  •  1
  •   Harikrishnan    3 年前

    const getTreeItemsFromData = (treeItems) => {
      //e.stoppropagation();
      return treeItems.map((treeItemData) => {
        let children = undefined;
        if (treeItemData.children && treeItemData.children.length > 0) {
          children = getTreeItemsFromData(treeItemData.children);
        }
        return (
          <TreeItem
            key={treeItemData.id}
            nodeId={treeItemData.id}
            label={treeItemData.name}
            children={children}
          />
        );
      });
    };
    
    export default function UpdateFieldObservations({
      formdata,
      handleChangeParent
    }) {
      const [matrixData, setMarixData] = useState([]);
    
      const airdata = [
        {
          id: 1,
          name: "Soil Vapour",
          children: [
            {
              id: 11,
              name: "Grab Sample"
            },
            {
              id: 12,
              name: "Insitu Meter Reading"
            }
          ]
        }
      ];
    
      console.log("Call API with matrixId : " + form.matrixId);
      useEffect(()=>{
      axiosInstance
        .get("/observations/" + form.matrixId, {
          headers: { "Content-Type": "application/json" }
        })
        .then((res) => {
          console.log(res);
          setMatrixData(res)
        })
        .catch((err) => {
          console.log("Error: " + err);
        });
      },[])
    
      return (
        <>
          <TreeView
            className={classes.root}
            defaultCollapseIcon={<ExpandMoreIcon />}
            defaultExpandIcon={<ChevronRightIcon />}
            onNodeSelect={handleNodeSelected}
          >
            {getTreeItemsFromData(airdata)}
          </TreeView>
        </>
      );
    }

    您需要获取useEffect内部的API。如果在API调用后设置一个状态,它会触发组件重新渲染,那么API将被再次调用,因此它会导致无限的API调用