在useEffect运行之前等待值

时间:2020-05-13 14:04:23

标签: javascript reactjs react-hooks

我有一个注册效果挂钩的函数,但是它失败了,因为在效果内部,我需要一个尚未定义的对象。通过调试,我注意到在执行异步回调之后填充了对象(在这种情况下为publicTypeIndex)。

这是我的代码:

export function useNotesList() {

  const publicTypeIndex: any = usePublicTypeIndex();
  const [notesList, setNotesList] = React.useState<TripleDocument>();

  React.useEffect(() => {

    if (!publicTypeIndex) {

      return;
    }

    (async () => {

      const notesListIndex = publicTypeIndex.findSubject(solid.forClass, schema.TextDigitalDocument);

      if (!notesListIndex) {

        // If no notes document is listed in the public type index, create one:
        const notesList = await initialiseNotesList()

        if (notesList == null) {

          return;
        }

        setNotesList(notesList);
        return;
      }  else {

        // If the public type index does list a notes document, fetch it:
        const notesListUrl = notesListIndex.getRef(solid.instance);

        if (typeof notesListUrl !== 'string') {

          return;
        }
        const document = await fetchDocument(notesListUrl);
        setNotesList(document);
      }
    })();

  }, [publicTypeIndex])

  return notesList;
}

usePublicTypeIndex函数的编写方式如下:

export async function usePublicTypeIndex() {
  const [publicTypeIndex, setPublicTypeIndex] = React.useState<TripleDocument>();

  React.useEffect(() => {
    fetchPublicTypeIndex().then(fetchedPublicTypeIndex => {
      if (fetchedPublicTypeIndex === null) {

        console.log("The fetched public type index is null");
        return;
      }
      console.log("Fetched Public Type Index: ");
      console.log(fetchedPublicTypeIndex);
      setPublicTypeIndex(fetchedPublicTypeIndex);
    });
  }, []);

  return publicTypeIndex;
}

我想找到一种在执行usePublicTypeIndex()代码之前等待publicTypeIndex.findSubject(solid.forClass, schema.TextDigitalDocument);函数返回的方法。最好的方法是什么?

谢谢

3 个答案:

答案 0 :(得分:0)

return中的

useEffect用作componentWillUnmount,主要用于清洁。

对于您而言,只需将async函数移到if块中


  if (publicTypeIndex) {

  (async () => { ... }
}

答案 1 :(得分:0)

useEffect始终会在组件安装后至少渲染一次。.在使用React Weather应用程序时,我遇到了与您以前相同的问题。

我使用useRef来解决此问题:

// to stop the useEffect from rendering when the app is mounted for the first time
    const initialMount = useRef(true);

useEffect(() => {
        // to stop useEffect from rendering at the mounting of the app
        if (initialMount.current) {
            initialMount.current = false;
        } else {
            if (publicTypeIndex) {  
               // do all the stuff you have to do after your object is populated
            }
        }   
    },[publicTypeIndex]);

答案 2 :(得分:0)

从技术上来说,您所做的是正确的,没有更好的方法来等待道具,因为无论如何回调都会运行。但是您可以稍微清理一下代码,例如:

  React.useEffect(() => {
    if (publicTypeIndex) {
      (async () => {
        const notesListIndex = publicTypeIndex.findSubject(
          solid.forClass,
          schema.TextDigitalDocument
        );

        if (!notesListIndex) {
          // If no notes document is listed in the public type index, create one:
          const notesList = await initialiseNotesList();

          if (notesList !== null) {
            setNotesList(notesList);
          }
        } else {
          // If the public type index does list a notes document, fetch it:
          const notesListUrl = notesListIndex.getRef(solid.instance);

          if (typeof notesListUrl === 'string') {
            const document = await fetchDocument(notesListUrl);
            setNotesList(document);
          }
        }
      })();
    }
  }, [publicTypeIndex]);

基本上,这些收益没有意义,您可以轻松检查所需条件,然后调用代码。