通过useEffect重新渲染后,React页面滚动在顶部

时间:2019-10-11 23:23:55

标签: javascript reactjs tabs material-ui react-hooks

我的问题-每当我使用<Tabs>组件时,onChange方法都会调用handleTabChange函数。再次调用该组件,并在重新粉刷useEffect之后调用该组件。这使我的页面在顶部滚动。

如何确保handleChangeuseEffect不会导致页面在顶部滚动?

export function VarianceGraph({ variancesGraphData }) {
  if (variancesGraphData === undefined) {
    return null;
  }
  const [currentProject, setCurrentProject] = useState('All');
  const [currentTab, setCurrentTab] = useState('ABCD');
  const projectCodes = prepareProjectCodesForConsumption(variancesGraphData);
  let data = {};

  function handleProjectChange(event) {
    const { value } = event.target;
    setCurrentProject(value);
  }

  function handleTabChange(event, tabValue) {
    setCurrentTab(tabValue);
  }

  data = prepareProjectDataForRechartsConsumption(currentProject, variancesGraphData);
  const hideABCD = data.ABCD.length < 1;
  const hideBCDF = data['BCDF'].length < 1;

  useEffect(() => {
    if (hideABCD && hideBCDF) {
      setCurrentTab('None');
    } else if (hideABCD) {
      setCurrentTab('BCDF');
    } else if (hideBCDF) {
      setCurrentTab('ABCD');
    }
  });

  return (
    <Grid container direction="row" justify="flex-start" alignItems="flex-start">
      <Grid item xs={12}>

我已经尝试过-

我需要在某些函数中使用setCurrentTab,以免无限渲染。

我尝试使用useLayoutEffect,但是它具有相同的行为。

如果需要,我可以进一步编写组件代码。请帮忙。预先感谢。

2 个答案:

答案 0 :(得分:1)

我继续搜索问题,找到了以下解决方案

Keep scroll-y after rerender

但是问题是getSnapshotBeforeUpdate在钩子中不可用 如此处所示

getSnapshotBeforeUpdate using react hooks

因此,最好的选择是将组件转换为类组件,然后按照此处的示例操作:https://reactjs.org/docs/react-component.html#getsnapshotbeforeupdate

根据您的示例代码,您可能必须绑定document.body.scrollHeight

class ScrollingList extends React.Component {
  constructor(props) {
    super(props);
    this.listRef = React.createRef();
  }

  getSnapshotBeforeUpdate(prevProps, prevState) {
    // Are we adding new items to the list?
    // Capture the scroll position so we can adjust scroll later.
    if (prevProps.list.length < this.props.list.length) {
      const list = this.listRef.current;
      return list.scrollHeight - list.scrollTop;
    }
    return null;
  }

  componentDidUpdate(prevProps, prevState, snapshot) {
    // If we have a snapshot value, we've just added new items.
    // Adjust scroll so these new items don't push the old ones out of view.
    // (snapshot here is the value returned from getSnapshotBeforeUpdate)
    if (snapshot !== null) {
      const list = this.listRef.current;
      list.scrollTop = list.scrollHeight - snapshot;
    }
  }

  render() {
    return (
      <div ref={this.listRef}>{/* ...contents... */}</div>
    );
  }
}

答案 1 :(得分:0)

如果我理解正确,则只希望useEffect渲染后VarianceGraph代码运行一次。

尝试向您的[]添加第二个参数useEffect,否则useEffect中的代码将在任何状态更改后运行。