React 滚动到文本区域底部

3

我正在向文本区域添加文本,然后尝试滚动到底部以保持最新内容可见。但是,在执行此操作时,似乎会使浏览器崩溃/内存不足。有人能帮助优化这段代码吗?

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

完整的

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

谢谢

3个回答

8

使用较新的React.createRef()更容易,并使用componentDidUpdate()作为触发器:

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

.current 属性是什么?原来添加这个属性是使它正常工作所必需的。” - MathKid

4

如果你有一个引用,就不需要使用ReactDOM.findDOMNode,只需检查引用是否为null,然后更改scrollTop

像这样:

scrollToBottom = () => {
    if(this.textLog){
        this.textLog.scrollTop = this.textLog.scrollHeight;
    }
};

是的,你可能是对的。我在很多应用程序中使用流程,并且在使用引用之前必须这样做,但如果没有它,你可能不会收到警告。 - Dakota
是的,抱歉,我已经修复了它。 - Dakota
我在代码中进行了更改,现在它不再滚动到底部了? - Elliot Reeve
在完整的componentDidMount()中添加了。谢谢帮忙。 - Elliot Reeve
让我们在聊天中继续这个讨论 - Elliot Reeve
显示剩余3条评论

1

我为了弄清楚这个问题而苦苦挣扎了很长时间。我有一个使用ReactJS的应用程序,它从运行在一台机器上的服务中读取日志文件,并且我希望最新的日志消息能够滚动到视图中。以下是我使用React Hooks编写的LogFileTextBox控件的一个相对完整的示例:

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>&nbsp;</Row>
        <Row>&nbsp;</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;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接