首页 > 解决方案 > 为什么当它的数组依赖发生变化时没有触发使用效果?

问题描述

所以几乎我必须执行两次 API 调用来获取一些数据,然后用这些数据更新状态(两个数组:allOrgList 和 PatientOrgList)。接下来我需要比较这两个数组的状态并找出它们之间的差异,然后将其更新为状态。

我想要做的是使用 useEffect 来跟踪这两个数组,并在它们更改时运行 diffing 函数。然而,触发这个 diffing 函数的 useEffect 永远不会被调用。尽管 allOrgList 和 patientOrgList 正在从空数组变为具有多个项目的数组。

我已经尝试使依赖项 [allOrgList.length, patientOrgList.length] 和 [JSON.stringify(allOrgList.length), JSON.stringify(patientOrgList.length)] 这将更新我的 diffedOrgOptions 状态,但它会继续调用 useEffect 和我收到一个错误,说重新渲染太多。

这是一些代码:

const [diffedOrgOptions, setDiffedOrgOptions] = useState([]);
const [allOrgList, setAllOrgList] = useState([]);
const [patientOrgList, setPatientOrgList] = useState([]);

  const getAllOrgs = () => {
    console.log('Get all org fires')
    const tempOrgList = [];

    trackPromise(
      GetAllOrganization()
        .then(data => {
          data.forEach(ele => tempOrgList.push({name: ele.name, organization_cis_id: ele.organization_cis_id}))
        })
        .then(setAllOrgList(tempOrgList))
        .catch(error => console.log(error))
    );
  };

  const getPatientOrgs = () => {
    const tempOrgList = [];

    props.patientDetails[0].organization_cis_ids.forEach(orgId => {
      trackPromise(
        GetOrganizationName(orgId)
          .then(data => tempOrgList.push({name: data[0].name, organization_cis_id: orgId}))
          .catch(error => console.log(error))
      )
    });

    setPatientOrgList(tempOrgList);
  };

  const diffOrgLists = () => {
    const tempDiffedOptions = [];
    const diffedList = allOrgList.filter(({ name: name1 }) => !patientOrgList.some(({ name: name2 }) => name2 === name1));
    diffedList.forEach(orgObj => tempDiffedOptions.push(({value: orgObj.organization_cis_id, label: orgObj.name})));
    setDiffedOrgOptions(tempDiffedOptions);
  };

  useEffect(() => {
    getPatientOrgs();
    getAllOrgs();
  }, []);

  useEffect(() => {
      if (allOrgList.length) {
      diffOrgLists();
    }
  }, [patientOrgList, allOrgList]);

标签: javascriptreactjsreact-hooks

解决方案


有些地方出错了,我试图用更现代的方式重写它,请仔细看看。还要考虑useMemo钩子以及map函数的使用,因为这似乎在您的工具链中缺失。我删除了 trackPromise 的用法,因为我认为这让您完全感到困惑。从使用 async/await 开始,然后再次查看文档并使用 hooks 实现 trackPromise

  const [diffedOrgOptions, setDiffedOrgOptions] = useState([]);
  const [allOrgList, setAllOrgList] = useState([]);
  const [patientOrgList, setPatientOrgList] = useState([]);

  const getAllOrgs = useCallback(async () => {
    console.log("Get all org fires");
    const tempOrgList = (await GetAllOrganization()).map(
      ({ name, organization_cis_id }) => ({
        name,
        organization_cis_id
      })
    );
    setAllOrgList(tempOrgList);
  }, []);

  const getPatientOrgs = useCallback(async () => {
    const tempOrgList = await Promise.all(
      patientDetail.organization_cis_ids.map(async (orgId) => {
        const [{ name }] = await GetOrganizationName(orgId);
        return { name, organization_cis_id: orgId };
      })
    );
    setPatientOrgList(tempOrgList);
  }, [patientDetail.organization_cis_ids]);

  const diffOrgLists = useCallback(() => {
    const diffedList = allOrgList
      .filter(
        ({ name: name1 }) =>
          !patientOrgList.some(({ name: name2 }) => name2 === name1)
      )
      .map((orgObj) => ({
        value: orgObj.organization_cis_id,
        label: orgObj.name
      }));
    setDiffedOrgOptions(diffedList);
  }, [allOrgList, patientOrgList]);

  useEffect(() => {
    getPatientOrgs();
    getAllOrgs();
  }, [getPatientOrgs, getAllOrgs]);

  useEffect(() => {
    if (allOrgList.length) {
      diffOrgLists();
    }
  }, [diffOrgLists, allOrgList]);

推荐阅读