newguy newguy - 1 month ago 5
React JSX Question

how can I make a scrollable component that scrolls to the latest children components

I am building a small chat program in reactjs. What I am going to do is to build a component which renders as a

<div>
tag dom. And I am appending children components which are also
<div>
tag doms onto this component. Then if the children components have used all the space of the parent component it should be able to scroll. How to do this in reactjs?

Suppose my child component is this:

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


and here is the parent component:

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>
);
}
}


The parent component can't scroll now. Can I just change its css style to make it work properly?

Answer

To achieve that you want to implicitly set height of the parent-div and set overflow-y: scroll like this:

.parentDiv {
    height: 300px;
    overflow-y: scroll;
}

How to scroll to the last child element?

To achieve that you could refactor your MessageBoard component like this:

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();
            }} ..>
                ...
            </div>
        );
    }
}

What we do here?

We set ref attribute using callback function that will be invoked right after component's been mounted into DOM and (if set on HTML element) on every update.

Callback function gets one parameter (in case of HTML element it is an actual DOM node reference) which we save in a separate variable (because parameter may be null on next call) then we get the last children of the component using the variable and invoke a native scrollIntoView() to scroll the parent to the bottom.