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

Infinite API calls on changing state in callback

我正在尝试将数据从 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 调用开始。我做错了什么以及如何最好地将此数据加载到树而不是 airdata

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 调用