簡體   English   中英

異步 Function 調用父組件

[英]async Function call to Parent Component

我有這個

const Parent = () => {
    [modalOpen, setModal] = React.useState(false);

    return <Child
               open={modalOpen}
               closeModal={() => setModal(false)}
               functionFromParent={() => console.log('Logged')} />
}

然后

const Child = ({ functionFromStore, functionFromParent, closeModal }) => {
    async function foo() {
        try {
          await ...;
          functionFromStore();
          functionFromParent();
        } catch (error) {
          ....
        }
    }

    const bar = () => {
        foo();
        closeModal();
    }

    return <div
           style={{backgroundColor: 'hotpink', width: '10rem', height: '10rem' }}
           onClick={() => bar()}/>
}

零件。

<Parent />決定是否顯示<Child /> (它是Modal )。 <Child />具有三個函數, closeModal()functionFromParent() ,來自<Parent/ > 並且functionFromStore()來自redux通過dispatchToProps() 為了簡單起見,我留下了所有的connect(stateToProps, dispatchToProps)(...)東西。 但是讓我們假設<Child />直接連接到store

單擊<Child/>中的<div /> > 會執行bar() 這會導致<Child /> unmount ,因為調用了<Parent />中的closeModal() ,從而關閉了modal 但是, bar()也調用foo() ,作為async function。

await解決時,調用functionFromStore() ,但不調用functionFromParent() 我想知道這是為什么? 為什么來自store的 function 被調用,即使組件( <Child /> )已卸載,但不是來自父級的 function ?

此外,有沒有辦法調用functionFromParent() ,即使<Child />已卸載? 它以某種方式與functionFromStore()一起工作,有沒有辦法讓它與functionFromParent()一起工作?

我無法重現您描述的行為,但這可能是一個關閉問題,因為您多次設置 state 但在處理程序的關閉中有一個陳舊的 state 值

您可以通過將回調傳遞給 state 設置器來解決它: setSomeState(currentState=>({...currentState,changes})) ,這是一個完整的示例:

 function Parent() { const [state, setState] = React.useState({ showModal: true, showFoo: false, }); return ( <div> {state.showModal? ( <Child open={state.showModal} closeModal={() => setState(state => ({...state, showModal: false, })) } functionFromParent={() => setState(state => ({...state, showFoo: true, })) } /> ): ( 'Child is gone ' )} {state.showFoo? <Foo />: 'no foo'} </div> ); } function Child({ functionFromParent, closeModal }) { function foo() { setTimeout(() => { functionFromParent(); }, 1000); } const bar = () => { foo(); closeModal(); }; return <button onClick={bar}>click me</button>; } function Foo() { return 'hi, I am Foo'; } ReactDOM.render( <Parent />, document.getElementById('root') );
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script> <div id="root"></div>

functionFromParent必須已被調用。 必須有其他原因導致問題。

 const Parent = () => { const [showChild, setShowChild] = React.useState(true); const childProps = { fnFromParent: () => { console.log("logging from fnFromParent"); }, unmount: () => { setShowChild(false); } }; return ( <div> <p>I'm a Parent</p> { showChild && <Child {...childProps} /> } </div> ); }; const Child = ({ fnFromParent, unmount }) => { const delayed = () => { const p = new Promise(res => setTimeout(res, 3000)) p.then(() => fnFromParent()); }; const clickHandler = () => { delayed(); unmount(); }; return <p onClick={clickHandler}>I'm a Child (click to remove me)</p>; }; ReactDOM.render(<Parent />, document.getElementById("root"));
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script> <div id="root"></div>

function Parent() {
  const [modalOpen, setModal] = React.useState(false);

  return (
    <Child
      open={modalOpen}
      closeModal={() => setModal(false)}
      functionFromParent={() => console.log("Logged")}
    />
  );
}

有沒有辦法調用 functionFromParent(),即使在卸載時? 它以某種方式與 functionFromStore() 一起工作,有沒有辦法讓它與 functionFromParent() 一起工作?

  • 是的! 當你的組件卸載時,你可以執行由 React 鈎子的useEffect提供的清理。 您可以看到下面的代碼,一旦您單擊div ,就會調用props.closeModal ,這將卸載您的Child組件。 一旦組件卸載, useEffect然后執行清理,它位於 useEffect 的return塊中,它調用您的functionFromParentfunctionFromStore
function Child(props) {
  useEffect(() => {
    return () => {
      props.functionFromStore();
      props.functionFromParent();
    };
  });

  return (
    <div
      style={{ backgroundColor: "hotpink", width: "10rem", height: "10rem" }}
      onClick={props.closeModal}
    />
  );
}

暫無
暫無

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

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