簡體   English   中英

react-fullpage-在渲染中避免setState無限循環

[英]react-fullpage - avoid setState infinite loop in render

TLDR問題:基本上,我想在頁腳打開時隱藏sidenav按鈕。

在我的App.js我正在呈現導航和react-fullpage(滾動到section組件),並傳遞isFooterOpen狀態和更改狀態的方法。

App.js

class App extends Component {
  state = { isFooterOpen: false };
  show = () => { this.setState({ isFooterOpen: true }); };
  hide = () => { this.setState({ isFooterOpen: false }); };

  render() {
    return (
      <React.Fragment>
        <Navigation
          isFooterOpen={this.state.isFooterOpen}
          hide={this.hide}
          show={this.show}
        />

        <FullPageWrapper
           isFooterOpen={this.state.isFooterOpen}
           hide={this.hide}
           show={this.show}
           {...fullpageOptions}
        />              
      </React.Fragment>
    );
  }
}

導航將狀態傳遞到sideButton,在此我基於它顯示/隱藏它,效果很好。

問題是,當我想從我的FullpageWrapper觸發狀態更改時,在該狀態中,我正在檢測是滾動到最后一節還是從最后一節向上滾動。

組件正在使用渲染道具,因此基本上我在渲染中調用setState,這會導致無限循環,但我找不到訪問該狀態(方向,索引等)的解決方法。 甚至toggleFooter函數都感覺有些“ hacky”,因為我正在將屬性設置為該狀態對象,而不是通過該npm ReactFullpage組件以某種方式保持我自己的狀態。

FullpageWrapper.js

function toggleFooter(state, props) {
  if (state.callback === "onLeave") {
    if (state.direction === "down") {
      const emptySection = document.querySelector("#empty");
      if (emptySection.classList.contains("active")) {
        state.isFooterOpen = true;
        // props.show(); // change app state and hide side button - infinite loop here
      }
    } else if (state.direction === "up" && state.origin.index === 5) {
      state.isFooterOpen = false;
      // props.hide(); // change app state and hide side button - infinite loop here
    }
  }
}

const FullPageWrapper = fullpageProps => (
  <ReactFullpage
    {...fullpageProps}
    render={({ state, fullpageApi }) => {
      toggleFooter(state, fullpageProps);

      return (
        <div style={{ position: "relative" }}>
          <HeroSection />
          <AboutSection />
          <TeamSection />
          <ServicesSection />
          <ContactSection />
          <Empty />    
          <Footer isFooterOpen={state.isFooterOpen} />
        </div>
      );
    }}
  />
);

我也嘗試了簡單的事件總線,其中我從FullpageWrapper調度了一個事件,但是我仍然從渲染器調度它,所以這是同樣的問題...

我刪除了所有不必要的內容,這是codeandbox示例。

如果用if語句包裝setState調用,我想那會消除無限循環嗎?

我在這里創建了一個更新的代碼沙箱,它看起來像您設計的那樣起作用:

https://codesandbox.io/s/p39w4z51pq

show = () => { if(!this.state.isFooterOpen) { this.setState({ isFooterOpen: true }); } }; hide = () => { if(this.state.isFooterOpen) { this.setState({ isFooterOpen: false }); } };

暫無
暫無

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

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