2016-02-23 18 views
9

私はチャットのような方法でメッセージを表示する簡単な "コンソール"を書いています。メッセージは下から現れ、上に移動します。速度反応 - コンポーネントアップデート後のscrollTopのアニメーション

私は作業コードを持っていますが、新しい "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と私は自分の状況でそれを使用する方法を理解できません。すべての例は適用されないようです(あるいは、私はそれらを理解していないかもしれません)。

私は非常に反応しており、いくつかのコンセプトはまだ私を混乱させるので、理解してください。

私はjQueryを使いたくありません。

+0

ので、uがインクルードは、一部の作業を反応させ、uはPURを求めてrを得ました電子スクロール? – goldylucks

+0

はい、上記のコードは動作しています。私はスクロールをアニメーション化したいと思います。私はjQueryを使ってこれを行う方法を知っていますが、jQueryを反応させることは愚かだと感じています。一方、Reactアニメーションのプラグインは私の理解を逃れる。私は以前に "純粋な"ベロシティを使っていました。それをReactで使うことができればうれしいです。だから問題は事実上速度jについてですが、私は他の提案にも触れています。 –

+0

より正確なタイトルはb: "javascript scroll animation without jquery";それはここであなたをもたらしたhav:http://stackoverflow.com/questions/8917921/cross-browser-javascript-not-jquery-scroll-to-top-animation – goldylucks

答えて

3

velocity-reactプラグインは、Velocityのアニメーションを使用するためにすでに実装されたReactコンポーネントを提供します。

私は、スクロール機能もアニメーションを使って実装できると思いますが、Velocityライブラリにはscroll commandがあります。 Velocity-Reaction Pluginを公開し、アニメーションのインターフェース(コンポーネント)を提供します。 Velocityコマンドはサポートされていません。

ReactでVelocityコマンドを使用するのは簡単です。 あなたの質問に基づいてreact-velocity-scrollレポを作成しました。また、チャットのような方法でメッセージを送信/一覧表示するライブデモがあります。

Velocityライブラリはvelocity-reactionsプラグインを使用した例に含まれています。 Velocityのアニメーションを使用するために既に実装されたReactコンポーネントを提供するため、将来の高度なアニメーション用にプラグインを含めることをお勧めします。ただし、レポはアニメーションを使用しません。 Velocityライブラリのscrollコマンドのみを使用します。必要に応じて、Velocityライブラリを個別にインポートできます。

ただし、ここに私のコンポーネントがあります。 MessageItemコンポーネントに注目してください - 新しいメッセージが追加されたら、それまでスクロールしてください。

の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; 
関連する問題