javascript - velocity-react - 在组件更新后动画 scrollTop

标签 javascript animation reactjs velocity.js

我正在编写一个简单的“控制台”,以类似聊天的方式显示消息。消息从底部出现,并向上移动。

我有工作代码,但我想通过每次添加新的“li”时将容器滚动到底部来动画显示消息。

当前代码:

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

messages 属性来自父组件和商店。

我找到了这个速度插件:https://github.com/twitter-fabric/velocity-react而且我不知道如何在我的情况下使用它。所有示例似乎都不适用(或者我只是不理解它们)。

我对 react 还很陌生,有些概念仍然让我感到困惑,所以请理解。

我不想使用 jQuery。

最佳答案

velocity-react插件提供已实现的 React 组件以使用 Velocity 的动画。

我想滚动功能也可以通过动画实现,但是 Velocity 库有 scroll command .我已经审查了 velocity-react 插件,它为动画提供了接口(interface)(组件)。不支持 Velocity 命令。

在 React 中使用 Velocity 命令非常简单。 我创建了 react-velocity-scroll repo 基于你的问题,并且有一个以类似聊天的方式发送/列出消息的现场演示。

请注意,Velocity 库通过 velocity-react 插件包含在示例中。建议包含用于 future 高级动画的插件,因为它提供了已经实现的 React 组件以使用 Velocity 的动画。但是 repo 不使用任何动画。它仅使用 Velocity 库的滚动命令。如果您愿意,您可以独立导入 Velocity 库。

但是,这是我的组件。请关注 MessageItem 组件 - 添加新消息后,向下滚动到它。

应用

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;

消息列表

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;

消息项

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;

关于javascript - velocity-react - 在组件更新后动画 scrollTop,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35566357/

相关文章:

javascript - 通过引用更新作用域对象的 Angular - 问题

javascript - 访问 Node 中的构造函数变量。 js

swift - 我如何在 UIImageView 上放置摇动动画

java - 如何在屏幕上移动/动画单个子类对象而不移动其他子类?

javascript - mobx react 观察者组件在更新后不调用渲染

javascript - React componentWillUpdate 被调用两次

javascript - 在一个主指令中使用多个指令

IOS - 按钮从右侧动画滑入

css - 在某些情况下,div 的宽度会增加,即使我有溢出 :auto

javascript - 如何检查一个数组是否包含另一个数组的任何项目