I am apending text to a textarea then attempting to scroll to the bottom to keep the latest within view. However, in doing this I appear to be crashing the browser / running out of memory. Can anyone help optimise this code?
//Appending text and calling scroll function
this.setState({ transcriptText: this.state.transcriptText + resp.log })
this.scrollToBottom();
//Textarea
<TextArea
ref={textLog => this.textLog = textLog}
autosize={{ minRows: 10, maxRows: 15 }}
value={this.state.transcriptText}
>
</TextArea>
//Scrolling
scrollToBottom = () => {
const textLogContainer = ReactDOM.findDOMNode(this.textLog);
if(textLogContainer){
textLogContainer.scrollTop = textLogContainer.scrollHeight;
}
};
Full
componentDidMount() {
const socket = io.connect(process.env.REACT_APP_API_URL, { transports: ['websocket'] });
socket.emit('onboarding', { id: uploadId });
socket.on('transcript_log', function (resp) {
this.setState({ transcriptText: this.state.transcriptText + resp.log })
this.scrollToBottom();
}.bind(this));
}
Thanks
I am apending text to a textarea then attempting to scroll to the bottom to keep the latest within view. However, in doing this I appear to be crashing the browser / running out of memory. Can anyone help optimise this code?
//Appending text and calling scroll function
this.setState({ transcriptText: this.state.transcriptText + resp.log })
this.scrollToBottom();
//Textarea
<TextArea
ref={textLog => this.textLog = textLog}
autosize={{ minRows: 10, maxRows: 15 }}
value={this.state.transcriptText}
>
</TextArea>
//Scrolling
scrollToBottom = () => {
const textLogContainer = ReactDOM.findDOMNode(this.textLog);
if(textLogContainer){
textLogContainer.scrollTop = textLogContainer.scrollHeight;
}
};
Full
componentDidMount() {
const socket = io.connect(process.env.REACT_APP_API_URL, { transports: ['websocket'] });
socket.emit('onboarding', { id: uploadId });
socket.on('transcript_log', function (resp) {
this.setState({ transcriptText: this.state.transcriptText + resp.log })
this.scrollToBottom();
}.bind(this));
}
Thanks
Share Improve this question edited Dec 1, 2017 at 14:41 Elliot Reeve asked Dec 1, 2017 at 14:22 Elliot ReeveElliot Reeve 9416 gold badges23 silver badges40 bronze badges3 Answers
Reset to default 9It's easier to use the newer React.createRef()
and use componentDidUpdate()
as a trigger:
constructor(props) {
super(props);
this.textLog = React.createRef();
}
componentDidUpdate() {
this.textLog.current.scrollTop = this.textLog.current.scrollHeight;
}
render() {
return(
<textarea ref={this.textLog} value={this.state.transcriptText} />
);
}
You don't need to do ReactDOM.findDOMNode
when you have a ref, change it to just check if the ref is null and then change scrollTop
.
Like this
scrollToBottom = () => {
if(this.textLog){
this.textLog.scrollTop = this.textLog.scrollHeight;
}
};
I struggled long and hard to figure this out. I've got a ReactJS app that reads logfiles from services running on a machine, and I wanted the most recent log message to scroll into view. Here is a somewhat complete example of my LogFileTextBox control using React Hooks:
import { Row } from "react-bootstrap";
import { Col } from "react-bootstrap";
import { Container } from "react-bootstrap";
import { useRef, useEffect } from "react";
const LogFileTextBox = (props) => {
const logText = props.logText;
const logFileName = props.logFileName;
const textArea = useRef();
// After render, this scrolls the textArea to the bottom.
useEffect(() => {
const area = textArea.current;
area.scrollTop = area.scrollHeight;
});
return (
<div>
<Container fluid>
<Row> </Row>
<Row> </Row>
<Row>
<Col></Col>
<Col>
<h6>Current Log: {logFileName}</h6>
</Col>
<Col></Col>
</Row>
<Row>
<Col>
<textarea
value={logText}
readOnly={true}
ref={textArea} // This links the useRef() hook to this object in the dom
/>
</Col>
</Row>
</Container>
</div>
);
};
export default LogFileTextBox;