簡體   English   中英

我可以使用什么方法來等待所有子回調完成?

[英]What approach can I use to wait for all child callbacks to complete?

我試圖找出一種架構來允許父組件,等待所有子組件完成渲染,然后做一些工作。 不幸的是,在這種情況下,我需要在 React 之外進行渲染,而是異步完成。

這讓事情變得有點復雜。 因此,在我的示例中,我希望在所有ChildComponent customRender調用完成后,調用一次ParentComponent 中doSomethingAfterRender()函數。

我確實有一個潛在的解決方案,但感覺不是很干凈,那就是在doSomethingAfterRender()函數上使用去抖動。 如果可能的話,我更願意使用更具確定性的方法只調用一次這個函數。

我想知道是否有人有更好的建議來處理這個問題?

父組件.js

const Parent = (props) => {

    // This is the function I need to call
    const doSomethingAfterRender = useCallback(
        async (params) => {          
             await doSomething();             
        },
    );

    // Extend the child components to provide the doSomethingAfterRender callback down
    const childrenWithProps = React.Children.map(props.children, (child) => {
        if (React.isValidElement(child)) {
            return React.cloneElement(child, { doSomethingAfterRender });
        }

        return child;
    });

    return (
        <React.Fragment>
            <...someDOM....>
            {childrenWithProps}
        </React.Fragment>
    );
   
}

ChildComponent.js(這實際上是一個 HoC)

const withXYZ = (WrappedComponent) =>
    ({ doSomethingAfterRender, ...props }) => {

        // I need to wait for this function to complete, on all child components
        const doRender = useCallback(
            async () => {
                await customRender();

                // Call the doSomething... 
                if (doSomethingAfterRender) {
                    doSomethingAfterRender();
                }
            },
            [doSomethingAfterRender]
        );

        return (
            <React.Fragment>
                <... some DOM ...>
                <WrappedComponent {...props} renderLoop={renderLoop} layer={layer} />
            </React.Fragment>
        );
    };

應用程序.js

const Child = withXYZ(CustomWrappedComponent);

const App = () => {
   return {
      <ParentComponent>
         <Child />
         <Child />
         <Child />
      </ParentComponent>
   };
}

如果我理解正確的話。 我會做類似的事情: useState with useRef. 這樣我只會觸發一次父級,也就是當所有子級組件完成各自的異步任務時。

兒童.js

const child = ({ childRef, updateParent }) => {
  const [text, setText] = useState("Not Set");
   useEffect(() => {
    if (typeof childRef.current !== "boolean") {
      const display = (childRef.current += 1);
      setTimeout(() => {
        setText(`Child Now ${display}`);
          if (childRef.current === 2) {
          updateParent(true);
          childRef.current = false;
        }
      }, 3000);
    }
  }, []);

  return (
    <>
      <div>Test {text}</div>
    </>
  );
}

const Parent = ()=>{
  const childRef = useRef(0);
  const [shouldUpdate, setShouldUpdate] = useState(false);

  useEffect(() => {
    if (shouldUpdate) {
      console.log("updating");
    }
  }, [shouldUpdate]);

  return (
    <div className="App">
      {childRef.current}
      <Child childRef={childRef} updateParent={setShouldUpdate} />
      <Child childRef={childRef} updateParent={setShouldUpdate} />
      <Child childRef={childRef} updateParent={setShouldUpdate} />
    </div>
  );
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM