美文网首页
react 实现滚动条一直位于容易的底部

react 实现滚动条一直位于容易的底部

作者: 琪琪fjq | 来源:发表于2019-12-13 17:38 被阅读0次

    背景:js实现滚动条一直在底部靠的是元素的scrollTop和scrollHeight来实现的,可是在React中有些行不通。
    原理:在容器的底部添加一个空的div,使该div一直处于浏览器视口内,这样就可以让容器的滚动条位于底部。
    知识点:
    useState: 通过在函数组件里调用它来给组件添加一些内部 state, useState 唯一的参数就是初始 state
    useEffect:给函数组件增加了操作副作用的能力,它跟 class 组件中的 componentDidMount、componentDidUpdate 和 componentWillUnmount 具有相同的用途,只不过被合并成了一个 API。
    useRef:返回一个可变的 ref 对象,其 .current 属性被初始化为传入的参数(initialValue)。返回的 ref 对象在组件的整个生命周期内保持不变。
    Element.scrollIntoView() :让当前的元素滚动到浏览器窗口的可视区域内。
    方案一:用hooks实现

    import React, {useState, useEffect, useRef, PureComponent} from "react";
    import ReactDOM from "react-dom";
    import uuid from "uuid";
    
    function Scroll() {
        const [messages, setMessages] = useState([]);
    
        const addMessages = () => {
            setMessages(m => [...m, uuid()]);
        };
    
        const messagesEndRef = useRef(null);
    
        const scrollToBottom = () => {
            console.log(messagesEndRef.current)
            messagesEndRef.current.scrollIntoView({ behavior: "smooth" });
        };
    
        useEffect(scrollToBottom, [messages]);
    
        return (
            <div className="App">
                <button className="addButton" onClick={addMessages}>
                    Add message
                </button>
                <div style={{display:"flex", flexDirection:"column", height:"100px", overflow:"scroll", marginTop:"30px", border:"1px solid #000"}}>
                    {messages.map(message => (
                        <span key={message}>{message}</span>
                    ))}
                    <div ref={messagesEndRef} />
                </div>
            </div>
        );
    }
    const rootElement = document.getElementById("root");
    ReactDOM.render(<Scroll />, rootElement);
    

    方案二:用类组件实现

    import React, {useState, useEffect, useRef, PureComponent} from "react";
    import uuid from "uuid";
    class Scroll extends PureComponent {
        state= {
            messages: [],
            flag: false
        };
    
        componentDidUpdate(prevProps, prevState, snapshot) {
            const { message } = this.state;
            this.scrollToBottom();
    
        }
    
        scrollToBottom = () => {
            const messagesEndRef = document.getElementById("messagesEndRef");
            messagesEndRef.scrollIntoView({ behavior: "smooth" });
        };
    
        addMessages = () => {
            const { messages, flag } = this.state;
            // console.log(uuid());
            messages.push(uuid());
            this.setState({
                messages,
                flag:!flag
            })
        };
    
        render() {
            const { messages } = this.state;
            return (
                <div className="App">
                    <button className="addButton" onClick={this.addMessages}>
                        Add message
                    </button>
                    <div style={{display:"flex", flexDirection:"column", height:"100px", overflow:"scroll", marginTop:"30px", border:"1px solid #000"}}>
                        {messages.map(message => (
                            <span key={message}>{message}</span>
                        ))}
                        <div id="messagesEndRef" />
                    </div>
                </div>
            )
        }
    }
    export default Scroll
    

    个人推荐第一种方案,第二种方案可行但是操作DOM性能一般。

    相关文章

      网友评论

          本文标题:react 实现滚动条一直位于容易的底部

          本文链接:https://www.haomeiwen.com/subject/lgxqnctx.html