在使用 React Hooks 的 react-table 中,如何在 Cell 中发出 get 请求?

In react-table with React Hooks, how to make a get request inside Cell?

我已经使用 React-table 几天了,这是我第一次使用它,我 运行 遇到了一些我似乎无法完全解决的问题。我正在尝试构建一个 table,我可以在其中同时显示来自两个 API get 请求的数据,因为我不知道是否有办法将两个请求数据连接成一个对象,我不知道该怎么做,我试图通过 react-table Column Cell 本身内部的 get 请求访问一些数据。

我的情况是:我有两个对象,联系人和机构,联系人在他们的数据中有机构 ID 作为参数,我需要在 table 中显示联系人信息和机构的一些信息链接到它的机构,从联系人数据中存在的机构 ID 获取它。

这里是联系方式之一:

{
   "contact_id": "34378a25-fe8c-4c64-bd35-59eab3f30863",
   "institution_id": "ae1d0fe8-cce1-40ef-87d7-729dfbe9716d",
   "name": "Contato 2",
   "role": "Cargo 1",
   "phone_numbers": [],
   "emails": [],
   "createdAt": "2021-03-09T20:40:26.6863764Z",
   "updatedAt": "2021-03-09T20:40:26.686376448Z",
   "deleted": false
}

这是机构数据:

{
 "institution_id": "ae1d0fe8-cce1-40ef-87d7-729dfbe9716d",
  "name": "Matheus Salles Blanco",
  "socialReason": "teste",
  "cnpj": "99999999999999",
  "abbreviation": "Matheus",
  "website": "teste.com",
}

这是正在实施的代码,已简化为仅重要且有效的部分,但仅显示从联系人对象中获取的信息:

const Contacts = ({ match }) => {
  const [data, setData] = useState([]);
  const [institution, setInstitution] = useState();
  const dataRecoil = useRecoilValue(contactData);

  const handleContact = useCallback(async () => {
    const response = dataRecoil.data;
    if (response) {
      setData(response.filter((contact) => !contact.deleted));
    }
  }, [setData, dataRecoil]);

  useEffect(() => {
    handleContact();
  }, [handleContact]);

  const columns = useMemo(
    () => [
      {
        Header: 'Nome',
        accessor: 'name',
      },
      {
        Header: 'Sigla',
        accessor: 'abbreviation',
      },
      {
        Header: 'Nome Fantasia',
        accessor: 'institution_id',
      },
    ],
    [editToggle, handleDelete],
  );

  return (
    <>
      <Table columns={columns} data={data} />
    </>
  );
};

以及它的印刷品:

这是我一直在尝试做的事情:

const Contacts = ({ match }) => {
  const [data, setData] = useState([]);
  const [institution, setInstitution] = useState();
  const dataRecoil = useRecoilValue(contactData);

  const handleContact = useCallback(async () => {
    const response = dataRecoil.data;
    if (response) {
      setData(response.filter((contact) => !contact.deleted));
    }
  }, [setData, dataRecoil]);

  useEffect(() => {
    handleContact();
  }, [handleContact]);

  const columns = useMemo(
    () => [
      {
        Header: 'Nome',
        accessor: 'name',
      },
      {
        Header: 'Sigla',
        accessor: 'abbreviation',
      },
      {
        Header: 'Nome Fantasia',
        accessor: 'institution_id',
        Cell: async ({ cell }) => {
          const response = await getInstitutionById(cell.row.values.institution_id);
          const result = [response.data];
          const inst = result.map((inst) => {return inst.name});
          const institution_name = inst[0];
          console.log(institution_name);
          return institution_name;
        },
      },
    ],
    [editToggle, handleDelete],
  );

  return (
    <>
      <Table columns={columns} data={data} />
    </>
  );
};

它在获取正确数据的级别工作,但不呈现页面并显示错误:

错误

console.log

中显示的正确数据

预期的输出是在 console.log 上显示这些名称,而不是第一张图片的长 ID。

那么,是否可以做我想做的事情?如果是这样,我可能做错了什么?

我认为问题在于您正在为您的单元格提供异步函数,这将 return 一个 Promise,而不是您期望的机构名称。

一个可能的解决方案是创建一个使用状态来存储机构名称的自定义 Cell 组件。我在下面提供了一个示例,它是由 this example 指导的,但是我根本没有测试代码,所以更多地使用它作为指南。

const MyCell = ({ cell }) => {

  const [institutionName, setInstitutionName] = useState('fetching...')

  useEffect(() => {
    const getInstitutionName = async (id) => {
      const response = await getInstitutionById(id);
      const result = [response.data];
      const inst = result.map((inst) => {return inst.name});
      const institution_name = inst[0];
      console.log(institution_name);
      setInstitutionName(institution_name)
    }

    getInstitutionName(cell.row.values.institution_id)
  }

  return institutionName
}

const Contacts = ({ match }) => {
  const [data, setData] = useState([]);
  const [institution, setInstitution] = useState();
  const dataRecoil = useRecoilValue(contactData);

  const handleContact = useCallback(async () => {
    const response = dataRecoil.data;
    if (response) {
      setData(response.filter((contact) => !contact.deleted));
    }
  }, [setData, dataRecoil]);

  useEffect(() => {
    handleContact();
  }, [handleContact]);

  const columns = useMemo(
    () => [
      {
        Header: 'Nome',
        accessor: 'name',
      },
      {
        Header: 'Sigla',
        accessor: 'abbreviation',
      },
      {
        Header: 'Nome Fantasia',
        accessor: 'institution_id',
        Cell: MyCell
      },
    ],
    [editToggle, handleDelete],
  );

  return (
    <>
      <Table columns={columns} data={data} />
    </>
  );
};