I have the below react component which is essentially a chat-box
render(){
const messages = this.props.messages;
return(
<div id="project_chat">
<h1>{this.props.project[0].project}</h1>
<div className="chat_room">
<div className="messages" ref="messages">
<Waypoint onEnter={this.activateWayPoint}/>
<ul>
{messages.map((message) => {
return(
<Message key={uuid.v4()} message={message}/>
)
})}
</ul>
</div>
<div className="chat_message_box">
<input type='text' onChange={this.handleChange} value={this.state.message} className="message_box" placeholder="enter message"/>
<button className="submit_message" onClick={this.handleSubmit}>Submit</button>
</div>
</div>
</div>
)
}
the problem i faced is the chat messages box starts at the topmost position of the container (scroll position starts at the top). I wanted the scroll position to be at the bottom like a normal chat room.
so i tried doing this:
componentDidMount(){
this.refs.messages.scrollTop = this.refs.messages.scrollHeight
}
this triggers AFTER the component gets mounted i.e - the message box scroll position initially starts at the top and forces its way to the bottom on render.
this is normally fine but i'm using a library called react-waypoint
which would help me paginate chat messages. this gets triggered every time i'm at the top of the container.
the unhappy consequence is that because the message box starts at the top initially on mount, the waypoint always gets triggered on mount as well.
my question is whether i can force the message component to start at the bottom position as opposed to starting the top and going to the bottom at the beginning
I tried doing this
componentWillMount(){
this.refs.messages.scrollTop = this.refs.messages.scrollHeight
}
the problem is i dont have access to refs before the component mounts. is there any other way?
What you want is to avoid firing this.activateWayPoint
before you've set scrollTop
.
You can do this by setting a state variable waypointReady
to false
initially. Set it to true in componentDidMount
.
Then, you can modify this.activateWayPoint
to check this.state.waypointReady
, and return immediately if it is false.
// inside component
getInitialState() {
return { waypointReady : false }
}
componentDidMount() {
this.refs.messages.scrollTop = this.refs.messages.scrollHeight;
this.setState({ waypointReady : true});
}
activateWayPoint() {
if (! this.state.waypointReady) return;
// Your code here!
// ...
}
You will probably have to bind this
inside your render
function:
// ...
<Waypoint onEnter={this.activateWayPoint.bind(this)}/>
// ...
Alternately, instead of performing the check inside this.activateWayPoint
, you might perform the check inside render:
// ...
<Waypoint onEnter={
this.state.waypointReady ?
this.activateWayPoint :
null
}/>
// ...
This assumes that your component re-renders every time you setState
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With