velocity-react - animating scrollTop after component update

試著忘記壹切 提交于 2021-02-07 12:13:57

问题


I'm writing a simple "console" that shows messages in a chat-like manner. With messages appearing from the bottom, and moving up.

I have the working code, but I'd like to animate the appearing messages by scrolling the container to the bottom each time a new "li" is added.

Current code:

import React from 'react';
import { render, findDOMNode } from 'react-dom';


export default React.createClass({
    componentDidUpdate : function(){
        var node = findDOMNode(this);
        node.scrollTop = node.scrollHeight;
    },
    render() {
        return (
            <ul id="log">
            {
                this.props.messages.map(function(message, index){
                    return <li key={index}>[{message.time.format('HH:mm:ss')}] {message.action}</li>
                })
            }
            </ul>
        )   
    }
})

The messages prop comes from the parent component and the store.

I found this velocity plugin: https://github.com/twitter-fabric/velocity-react and I can't figure out how to use it in my situation. All the examples don't seem to apply (or maybe I just don't understand them).

I'm quite new to react, and some concepts still confuse me, so please be understanding.

I don't want to use jQuery.


回答1:


The velocity-react plugin provides already implemented React components for using Velocity's animations.

I guess that the scroll functionality can be implemented via animations too, but Velocity library has scroll command. I've reveiwed velocity-react plugin and it provides interface (components) for the animations. There isn't any support for the Velocity commands.

It's pretty easy to use Velocity commands in React. I've created react-velocity-scroll repo based on your question and there is a live demo of sending/listing messages in a chat-like manner.

Please note that the Velocity library is included in the example via velocity-react plugin. Its recommended to include the plugin for future advanced animations, because it provides already implemented React components for using Velocity's animations. However the repo don't use any animations. It uses only Velocity library's scroll command. If you prefer - you can import Velocity library independently.

However, here are my components. Please focus on MessageItem component - once a new message is being added, then scroll down to it.

App

import React from 'react';
import MessagesList from './MessagesList';

const style = {
    textAlign: 'center'
};

class App extends React.Component{
    constructor(props) {
        super(props);

        this.state = {
            /**
             * @type Array - Store sent messages
             */
            messages: [],
            /**
             * @type String - Store the input value.
             * It's reset on message sent
             */
            text: ''
        }
    }

    handleOnChange(e) {
        const text = e.target.value;
        this.setState({ text });
    }

    handleOnKeyPress(e) {
        const text = e.target.value;

        // Send the message on `Enter` button press
        if (e.key === 'Enter') {
            this.sendMessage(text);
        }
    }

    /**
     * Add the message to the state and reset the value
     * of the input
     *
     * @param String text - Message text
     */
    sendMessage(text) {
        const { messages } =  this.state;
        const message = { date: new Date(), text };

        this.setState({
            messages: messages.concat([message]),
            text: ''
        });
    }

    render() {
        const { messages, text } = this.state;

        return <div style={style}>
            <h1>Please enter your text message:</h1>

            <input
                value={text}
                placeholder="Press Enter for sending"
                onChange={this.handleOnChange.bind(this)}
                onKeyPress={this.handleOnKeyPress.bind(this)} />

            <MessagesList messages={messages} />
        </div>
    }
}

export default App;

MessagesList

import React from 'react';
import MessageItem from './MessageItem';

const style = {
    height: '100px',
    overflowY: 'scroll'
};

const MessagesList = (props) => {
    let { messages } = props;

    messages = messages.map( function(message, index){
        return <MessageItem key={index} index={index} message={message} />
    });

    return <ul style={style}>{messages}</ul>
};

export default MessagesList;

MessageItem

import React from 'react';
import ReactDOM from 'react-dom';
const Velocity = require('../node_modules/velocity-react/lib/velocity-animate-shim');

const style = {
    listStyle: 'none'
};

class MessageItem extends React.Component{
    componentDidMount() {
        const parentNode = ReactDOM.findDOMNode(this).parentNode;
        const node = ReactDOM.findDOMNode(this);

        // Once a new item is being added, then scroll down to it
        Velocity(node, 'scroll', {
            duration: 500,
            container: parentNode,
            queue: false
        });
    }

    render() {
        const { message } = this.props;

        return <li style={style}>{message.date + ' - ' + message.text}</li>
    }
}

export default MessageItem;


来源:https://stackoverflow.com/questions/35566357/velocity-react-animating-scrolltop-after-component-update

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!