附加子组件时,如何使可滚动组件自动滚动到最新的子组件?

new*_*guy 1 scroll reactjs

我正在用reactjs构建一个小型聊天程序。我要做的是构建一个呈现为<div>标签dom 的组件。而且我要添加子组件,它们也是<div>标签域。然后,如果子组件已使用了父组件的所有空间,则它应该能够滚动。如何在reactjs中做到这一点?

假设我的子组件是这样的:

class Message extends Component {
    render() {
        return (
                <div className="message">
                    <strong>{this.props.user}</strong>:&nbsp;
                    <span>{this.props.text}</span>
                </div>
        );
    }
}
Run Code Online (Sandbox Code Playgroud)

这是父组件:

class MessageBoard extends Component {
    render() {
        return (
            <div className={this.props.styleClass}>
                <h2>{this.props.body}</h2>
                {
                    this.props.messages.map((message, i) => {
                        return (
                                <Message 
                                    key={i}
                                    user={message.user}
                                    text={message.text}
                                />
                            );
                    })
                }
            </div>
        );
    }
}
Run Code Online (Sandbox Code Playgroud)

父组件现在无法滚动。我可以更改其CSS样式以使其正常工作吗?

Kon*_*sky 5

为了实现这一点,您需要隐式设置heightparent-div并进行如下设置overflow-y: scroll

.parentDiv {
    height: 300px;
    overflow-y: scroll;
}
Run Code Online (Sandbox Code Playgroud)

如何滚动到最后一个子元素?

为此,您可以像下面这样重构MessageBoard组件:

class MessageBoard extends Component {
    render() {
        return (
            <div ref={function (element){
                if (element) {
                    this.messagesContainer = element;
                }
                let lastIndex = this.messagesContainer.length - 1;
                this.messagesContainer[lastIndex].scrollIntoView();
            }.bind(this)} ..>
                ...
            </div>
        );
    }
}
Run Code Online (Sandbox Code Playgroud)

我们在这里做什么?

我们ref使用回调函数设置属性,该回调函数将在组件安装到DOM之后(如果在HTML元素上设置)在每次更新后立即调用。

回调函数获取一个参数(对于HTML元素,它是实际的DOM节点引用),我们将其保存在单独的变量中(因为参数可能null在下一次调用中),然后使用该变量获取组件的最后一个子代,并调用本地scrollIntoView()父滚动至底部。