【问题标题】:componentDidUpdate scroll to bottom when item is loaded加载项目时,componentDidUpdate 滚动到底部
【发布时间】:2017-12-21 11:35:26
【问题描述】:

我有一个列表,我想滚动到底部,我的组件是这样编码的

class Msg extends Component {

    componentDidUpdate() {

        if(this.container){
            this.container.scrollTop = this.container.scrollHeight
        }
    }

    render() {
        return(
            <div ref={elem = this.container = elem}>
                <Item />
                <Item />
                <Item />
            </div>
        )
    }
}

成功了。但问题是每次组件重新渲染时它都会滚动。 Msg有很多子组件,触发子组件的状态会导致Msg组件重新渲染,如何解决?

像普通用户一样解释:

用户向上滚动列表,然后单击某处的下拉菜单,componentDidUpdate 触发,导致滚动到底部。

【问题讨论】:

  • 那么,您希望它什么时候向下滚动...当添加新项目时?我建议在 UX 中添加一个新按钮,允许用户在需要时向下滚动。
  • @camou 在 whatssap 的消息中,你看到一个按钮吗?
  • 不,但是当我在 iOS9.2 上向上滚动时,WhatsApp 不会强迫我向下滚动。那么,您希望何时向下滚动、何时有新消息或何时用户在最后几秒钟内停止向上滚动?

标签: javascript reactjs ecmascript-6


【解决方案1】:

要在组件第一次渲染时滚动到底部,您应该使用componentDidMount 生命周期钩子。

如果您希望列表在每次添加元素时滚动,您可以像现在使用的那样使用componentDidUpdate 钩子,但不是每次都操作滚动顶部,而是检查您正在渲染的项目数量是否发生了变化。现在每次组件更新时都设置滚动顶部。

componentDidUpdate 获取之前的 props 和之前的状态作为参数,所以你可以这样写:

componentDidUpdate(prevProps, prevState) {
    if (this.props.items.length > prevProps.items.length) {
        this.refs.container.scrollTop = this.refs.container.scrollHeight;
    }
}

这里是 reacts 生命周期钩子的一个很好的参考:http://busypeoples.github.io/post/react-component-lifecycle/

【讨论】:

  • 把这个this.refs.container.scrollTop = this.refs.container.scrollHeight; 放到componentDidMount 里面是不行的
  • 您在列表中呈现什么?例如。对于图像,在 componentDidMount 期间 scrollHeight 可能仍为零,因为图像尚未加载并且不占用容器中的空间。
  • 图片和文字。
  • 您在 componentDidMount 中获得了一些滚动高度还是为零?如果您使用 setTimeout 来延迟获取 scrollHeight,您会得到什么吗? (仅用于调试。在没有超时的情况下破解滚动可能会导致更多麻烦)
【解决方案2】:

使用这样的东西 在列表末尾添加一个空白 div

&lt;div ref="blankdiv"&gt;&lt;/div&gt;

然后在每个componentDidMount 在屏幕中滚动这个 div

this.refs.blankdiv.scrollIntoView()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-09-18
    • 1970-01-01
    • 1970-01-01
    • 2016-04-07
    • 1970-01-01
    • 2015-09-10
    • 2016-12-12
    • 1970-01-01
    相关资源
    最近更新 更多