63
44

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

React-Scrollでsmoothなスクロールを実装してみた。

Last updated at Posted at 2019-06-09

#React初心者がreact-scrollでsmooth scrollを実装してみた話。

自分はまだYoutubeで見たTodoアプリのチュートリアルなどでReactをかじり始めた初心者ですが、今回は実際にコンポーネントごとでUIパーツを作り上げるという概念に慣れるためにも、自分の1ページポートフォリオサイトを作成してみました。

http://takkalghul.github.io/mioportfolio/
Image from Gyazo

こんな感じで、ページの一番下にある上矢印のボタンを押すとトップに戻り、
そのほかでは、navbarのリンクを押すとそれぞれのトピックまでスクロールされるようになっています。

###react-scrollをインストール

npm install react-scroll

githubに使用方法が載ってます。
https://github.com/fisshy/react-scroll

ですが今回私はこのブログを参考に作成しました。
https://scotch.io/tutorials/implementing-smooth-scrolling-in-react
こちらに詳しい使用方法や追加機能などの実装方法が載っています。

###scrollToTopの実装

react-scrollには様々なファンクションがパッケージに含まれており、scrollToTopやscrollToBottomなどで簡単に上下へのスクロールを行うことができます。

はじめに、一番下の上矢印をクリックするとトップに戻れるように、scrollToTopを実装していきます。
ちなみに、scrollToTopの矢印はTitile.jsの子コンポーネントであるScrollUp.jsに記述しています。

ScrollUp.js
import React, { Component } from 'react';
import { animateScroll as scroll } from 'react-scroll';
import './Title.css';

class ScrollUp extends Component {

  scrollToTop = () => {
    scroll.scrollToTop(); 
  };

  render() {
    return(
      <div className="scroll scroll-up">
        <div className="arrow bounce" style={{ bounce }}>
          <i onClick={this.scrollToTop} className="fa fa-chevron-circle-up" />
        </div>
      </div>   
    );
  }
  
}

const bounce = {
  animation: 'bounce 2s infinite',
  color: '#fff'
}

export default ScrollUp;

react-scrollからanimateScroll as scrollをimportして宣言します。

functionとしてscrollToTopを定義し、下矢印アイコンをクリックした時にイベントが発火するように
onClick={this.scrollToTop} をiタグ以降に記述していきます。

パッケージだとこの少ない記述だけで簡単にトップへのスクロールが可能になりますね。

Image from Gyazo

###リンクを押したらスクロール

自分はまだプログラミング学習を初めて3ヶ月なもので、まだ色々とわかってないことがたくさんあって、、、
特にreactでのcomponentの考え方がまだよくわかっていないものでこのスクロールの実装すら色々と考えすぎて悩んでましました。

例えば、それぞれのトピックをコンポーネントごとにこのように切り分けたので

App.js
import React, { Component } from 'react';
import './App.css';

import Nav from './Components/Nav';
import Title from './Components/Title';
import About from './Components/AboutMe';
import Works from './Components/Works';
import Contact from './Components/Contact';


class App extends Component {
  render () {
    return (
      <div className="app">
        <Nav />
        <Title />
        <About />
        <Works />
        <Contact />
      </div>   
    );
  }      
}

export default App;

Nav内にあるnavbarでのリンクを別のコンポーネントへアクセスさせるにはどうすればいいのかなとか、propsでデータを引き継がなきゃいけないのかなとか考えてましたが、react-scrollはとってもシンプルでした。

Nav.js
import React, { Component } from 'react';
import { Layout, Header, Navigation, Drawer } from 'react-mdl';
import { Link } from 'react-scroll';

class Nav extends Component {
  render() {
    return (
      <div className="demo-big-content">
        <Layout>
          <Header className="header" style={{ fontWeight: 'bold', fontSize: '45px'}} title= " " scroll>
            <Navigation className="navigation">
            <Link
              activeClass="active"
              to="title"
              spy={true}
              smooth={true}
              offset={-70}
              duration= {800}
              >Top</Link> 
            <Link
              activeClass="active"
              to="about"
              spy={true}
              smooth={true}
              offset={-70}
              duration= {800}
              >About</Link> 
            <Link
              activeClass="active"
              to="works"
              spy={true}
              smooth={true}
              offset={-70}
              duration= {800}
              >Works</Link> 
            <Link
              activeClass="active"
              to="contact"
              spy={true}
              smooth={true}
              offset={-70}
              duration= {800}
              >Contact</Link> 
            </Navigation>
          </Header>
          <Drawer title=" ">
            <Navigation>
            <Link
                activeClass="active"
                to="about"
                spy={true}
                smooth={true}
                offset={-70}
                duration= {1000}
                >About</Link> 
              <Link
                activeClass="active"
                to="works"
                spy={true}
                smooth={true}
                offset={-70}
                duration= {1000}
                >Works</Link> 
              <Link
                activeClass="active"
                to="contact"
                spy={true}
                smooth={true}
                offset={-70}
                duration= {1000}
                >Contact</Link> 
            </Navigation>
          </Drawer>
        </Layout>
      
      </div>
    )
  }
}
export default Nav;

react-router-domでも使用されるおなじみのLinkタグを使っていきます。

Linkの後にオプションをつけます。これはgithubにある公式のドキュメントからコピペできます。
to=には移遷したい先のIdを指定しましょう。
smoothスクロールを実装するため、smoothはtrueにしておきます。offsetはpadding-topのようなもので、移遷する位置を指定できます。durationにはスクロールする秒数を指定しましょう。

今回自分はreact-mdlを使用していますので、他のタグなどはお気になさらずに。。

完成版がこちら↓

Image from Gyazo

###便利機能

今回のポートフォリオのnavbarにも使用しているこれ↓ですが
Image from Gyazo

これもreact-scrollで実現できるものです。
しかしながら使用したのはCSSですが。。。

先ほどのLinkタグに追加したactiveClassですが、これがactiveの状態であること = 指定した位置にスクロールしてきた時といういこと。

その時にborder-bottomが適用されるようにCSSを記述しただけです。

App.css
.navigation > .active {
  border-bottom: 2px solid #fff;
}

###おしまい

react-smooth-scrollなどたくさんのscroll用パッケージが存在しますが、自分はこれが一番シンプルで簡単なのではないかと感じました。

reactに関する知識(JavaScript自体)がまだまだなので、これからはGatsbyやReduxを使ってブログなどを作成しながら学んでいこうと思います。

#####参考
Implementing Smooth Scrolling in React
https://scotch.io/tutorials/implementing-smooth-scrolling-in-react
github fisshy
https://github.com/fisshy/react-scroll

63
44
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
63
44

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?