简体   繁体   English

在React中重新渲染组件后的页面scroll_to #id

[英]page scroll_to #id after component re-rendered in React

I have a component JumpList, which is a side panel with links of two categorys (A an B), which each have subcategories (A1, A2, A3, and B1, B2, B3). 我有一个组件JumpList,它是一个带有两个类别(A和B)链接的侧面板,每个类别都有子类别(A1,A2,A3和B1,B2,B3)。 My component ReactPage combines the JumpList with the content for the page, which can either be ContentPageA or ContentPageB, which correspond to the major categories. 我的组件ReactPage将JumpList与页面内容结合在一起,可以是ContentPageA或ContentPageB,它们与主要类别相对应。 Each of these pages has headers which correspond to the subcategories (ex. A1, A2, and A3). 这些页面中的每个页面都有对应于子类别(例如A1,A2和A3)的标题。

If the state of ReactPage is {a: true} the ContentPageA is rendered and clicking any of the A1-A3 links causes the page to scroll down to where those headers are on the page. 如果ReactPage的状态为{a:true},则呈现ContentPageA,单击任何A1-A3链接都会导致页面向下滚动到这些标题在页面上的位置。 Clicking any of B1-B3 changes the state of ReactPage to {a: false} and ContentPageB is rendered. 单击B1-B3中的任何一个,将ReactPage的状态更改为{a:false},并呈现ContentPageB。 What I'd like is for to also do the same scroll effect that clicking the same page links do, but the IDs used to reference these spots on the page do not exist at the time the code is run because React is not done rendering the page after the state change. 我还想获得与单击相同页面链接相同的滚动效果,但是在代码运行时不存在用于引用页面上这些位置的ID,因为没有完成React的渲染。状态更改后的页面。

Is there a way I can make it so that this process happens in a React-y way? 有什么办法可以使该过程以React-y方式发生? I could just hide the unused divs, and use toggling classes upon click, but that doesn't feel very Reacty (the truth of the DOM would change without a re-rendering) 我可以隐藏未使用的div,并在单击时使用切换类,但是感觉不太Reacty(DOM的真相将在不重新渲染的情况下发生变化)

some example code: 一些示例代码:

var ReactPage = React.createClass({
  getInitialState: function() {
    return {
      a: true
    };
  },

  handlePageChange(id, a){
    if ( a ){
      if (this.state.a === false){
        this.setState({a: true});
      }
    }else {
      if (this.state.b === true){
        this.setState({a: false});
      }
    }

    $('html, body').animate({
      scrollTop: $("#" + id).offset().top
    }, 1000);
  }

  render: function(){
    var content;
    if (this.state.a) {
      content = <ContentPageA></ContentPageA>
    }else{
      content = <ContentPageB></ContentPageB>
    }

    return (
      <div>
        <SideJumpPanel pageChangeCallback={this.handlePageChange}></SideJumpPanel>
        {content}
      </div>
    )
  }
});


var SideJumpPanel = React.createClass({
  propTypes: {
    pageChangeCallback: React.PropTypes.func
  },

  scrollTo: function(id){
    return function() {
      this.pageChangeCallback(id);
    }
  }

  render: function() {
    return (
      <div>
        Jump to:
        A:
        <ul>
          <li onClick={this.scrollTo('A1', true)}>A1</li>
          <li onClick={this.scrollTo('A2', true)}>A2</li>
          <li onClick={this.scrollTo('A3', true)}>A3</li>
        </ul>
        B:
        <ul>
          <li onClick={this.scrollTo('B1', false)}>B1</li>
          <li onClick={this.scrollTo('B2', false)}>B2</li>
          <li onClick={this.scrollTo('B3', false)}>B3</li>
        </ul>
      </div>
    )
  }
});

(I may have left something out of the sample code, it's mainly just to illustrate) (我可能在示例代码中遗漏了一些东西,主要是为了说明)

Just found a solution, but still curious if there is a more zen way to do this. 刚刚找到了解决方案,但仍然想知道是否还有禅宗方法。 One solution as suggested in the second answer to this question is to use window.requestAnimationframe 此问题的第二个答案中建议的一种解决方案是使用window.requestAnimationframe

React "after render" code? 反应“渲染后”代码?

You could just wrap your two pages in differents <div> an apply display: none; 您可以将两个页面包装成不同的<div>应用display: none; to the page you want to hide and display: block (or whatever display you want) to the page you want to show. 到要隐藏和display: block的页面display: block (或任何想要的显示)到要显示的页面。 ex: 例如:

<div id="A" style="display: block;">
  ... Your page A
</div>
<div id="B" style="display:none">
  ... Your page B
</div>

Then, in your js: 然后,在您的js中:

if(a){
  document.getElementById("A").style.display = "block";
  document.getElementById("B").style.display = "none";
} else {
  document.getElementById("B").style.display = "block";
  document.getElementById("A").style.display = "none";
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM