2017-10-01 11 views
0

私はReact TypescriptでAPPを作成しています。 Jqueryを可能な限り使用しないようにしています。React Typescriptのウィンドウのスクロールを検出します。

ウィンドウがスクロールした時点を検出して、ヘッダークラ​​スを更新できるようにする必要があります。これはjqueryの中で行われるだろうかです:

$(window).scroll(function() { 
    var scroll = $(window).scrollTop(); 
    if(scroll >= 200) { 
     $(".navbar-default").addClass("dark"); 
    } else { 
     $(".navbar-default").removeClass("dark"); 
    } 
    }); 

私のエントリポイントのHTMLは、この(削減)

<body> 
<noscript> 
    You need to enable JavaScript to run this app. 
</noscript> 
<div id="root"></div> 
<body> 

エントリTSXファイルを次のようになります。

import * as React from 'react'; 
import * as ReactDOM from 'react-dom'; 
import Layout from './views/layout/layout'; 
import registerServiceWorker from './registerServiceWorker'; 
import './index.css'; 
import { Provider } from 'react-redux'; 
import { createStore } from 'redux'; 
import { enthusiasm } from './reducers/index'; 
import { StoreState } from './types/index'; 

const store = createStore<StoreState>(enthusiasm, { 
    enthusiasmLevel: 1, 
    languageName: 'TypeScript', 
}); 

ReactDOM.render(
    <Provider store={store}> 
    <Layout /> 
    </Provider>, 
    document.getElementById('root') as HTMLElement 
); 
registerServiceWorker(); 

されるものこのタイプのイベントを複製するための推奨される方法は?

+0

テイクこれを見てください:https://github.com/shotaK/redux-lazy-scroll/blob/master/ReduxLazyScroll.js;まったく同じ機能を持つコンポーネントです。 – Shota

答えて

0

DOM要素ではなく状態を更新することを忘れないでください。 componentDidMountに新しいリスナーを追加する場合は、componentWillUnmountでリスナーも削除する必要があります。

componentDidMount: function() { 
    window.addEventListener('scroll', this.handleScroll); 
}, 

componentWillUnmount: function() { 
    window.removeEventListener('scroll', this.handleScroll); 
}, 

handleScroll: function(event) { 
//your code to handle scroll 
}, 
+0

私はこのようにすることを検討していました。このコードをスクリプトファイルの最初のHTMLページの一番下に配置しますか?どのようなREACT Typescriptコード内でもそうではありませんか? – michael

+0

@michael私はコードを編集しました。これはもっと反応する方法です。外部のものを使用できる場合は、[react-scroll](https://github.com/fisshy/react-scroll)ディレクティブをチェックすることもできます。それは使いやすく、かなり良いです。 – krzysztofla

0

私たちは、同様の問題を持っていて、私達は子供の機能を持つコンポーネントを構築することによってそれを解決し、そう

export interface ScrollElementProps { 
    children?: (isInRange) => any 
    throttle?: number 
    maxScroll?: number 
    minScroll?: number 
} 

export interface ScrollElementState { 
    isInRange: boolean 
} 

export default 
class ScrollElement extends React.Component<ScrollElementProps, ScrollElementState> { 
    static defaultProps: Partial<ScrollElementProps> = { 
    throttle: 200, 
    minScroll: 0, 
    maxScroll: Number.MAX_VALUE 
    }; 

    state: ScrollElementState = { 
    isInRange: false 
    }; 

    private listenToScroll = 
     _.throttle(this.props.throttle,() => this.scrollListener()); 

    componentWillMount() { 
    window.addEventListener('scroll', this.listenToScroll); 
    } 

    componentDidMount() { 
    this.listenToScroll(); 
    } 

    componentWillUnmount() { 
    window.removeEventListener('scroll', this.listenToScroll); 
    } 

    render() { 
    return this.props.children(this.state.isInRange); 
    } 

    private scrollListener() { 
    this.setState({ isInRange: this.isWithinScrollRange() }); 
    } 

    private isWithinScrollRange() { 
    const { minScroll, maxScroll } = this.props; 
    return _.inRange(minScroll, maxScroll, documentScrollTop()); 
    } 
} 

のようなそして、あなたはこのようにそれを使用することができます:

<ScrollElement maxScroll={200}> 
{isInRange => (
    <NavBar className={isInRange ? 'dark' : ''}/> 
)} 
</ScrollElement>