首页 > 解决方案 > 映射获取的数据

问题描述

我正在尝试在 react 中构建一个 TreeNode 函数,以构建一些数据的树形结构。

我以假数据为起点:

const fakeData = {
 "1234": {
   id: "1234",
   name: "Division",
   address: "string",
   childNodes: []
  }
};

当我使用“id”1234 展开“Division”节点时,我想获取该节点的子节点。所以我的 fakeData 扩展为这样的:

我正在使用 fetch() 方法获取数据,但我不确定如何将该数据传递给 Promise 的 resolve() 方法。现在我正在这样做:

function fakeAjax(url, id) {
  return new Promise((resolve, reject) => {
    fetch(url)
      .then(res => res.json())
      .then(result => {
        const nodes = result.map(node => node.id);
        resolve(fakeData[id].childNodes.map(nodes));
      });
  });
}

function fetchChildNodes(id) {
  return fakeAjax(`someUrl`, id);
}

function TreeNode({ id, name }) {
  const [childNodes, setChildNodes] = useState(null);

  // Toggle our display of child nodes
  const toggleExpanded = useCallback(() => {
      fetchChildNodes(id)
        .then(nodes => setChildNodes(nodes.map(node => <TreeNode {...node} />)))
    }
  }, [childNodes]);

但这不是将相关数据传递给 resolve 方法。难道我做错了什么?

标签: javascriptreactjs

解决方案


有几件事跳出来:

  1. 您的代码正在使用显式承诺创建反模式fetch返回一个承诺,没有必要new Promise环绕它。这不是问题,而是问题,尤其是因为fakeAjax写的方式,如果ajax调用失败,则返回的promisefakeAjax永远不会被拒绝(并且永远不会实现,它只是永远保持挂起状态)。

  2. 您正在调用map传入一个非函数作为映射函数:

    const nodes = result.map(node => node.id);
    resolve(fakeData[id].childNodes.map(nodes));
    // Here −−−−−−−−−−−−−−−−−−−−−−−−−−−−^
    

    这没有任何意义。map接受一个函数,而不是一个数组。

  3. 您的代码在fetch几乎所有其他人的 API 中都受到了打击:您需要检查请求是否在 HTTP 级别工作。fetch仅在出现网络错误时拒绝,而不是 HTTP 错误(更多信息请参见我的博客

  4. 我假设您的 ajax 调用返回您应该直接传递给的实际节点数据,TreeNode而不是修改(当然也不会变成仅id包含值的数组)。

所以像:

function fetchJSON(url) {
    return fetch(url)
      .then(res => {
          if (!res.ok) {
              throw new Error("HTTP error " + res.status);
          }
          return res.json();
      });
}

function fetchChildNodes(id) {
    return fetchJSON(`someUrl`, id);
}

节点数据到 的映射TreeNode发生在 中TreeNode,所以我认为您不需要在fetchChildNodes.


推荐阅读