0
0

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 1 year has passed since last update.

React, Redux でパージネーションのスクロール表示を実装する。

Posted at

忘れないように、メモ書き。

API

SQL は、SQLite を使っていました。

SELECT * FROM Hoge WHERE fuga="fuga1";

のような SQL文 を、LIMIT & OFFSET で 10件程度に分割する。

SELECT * FROM Hoge WHERE fuga="fuga1" LIMIT 10 OFFSET 10;

これに URL を付与 (Railsなら routes.rb、Djangoなら urls.py の url patterns、Express なら app.get('url', function(req, res) => ){} ) して、http://hoge-api.com/hoges?offet=num から hoge の num の offset からのデータを取得できるようにする。

Redux

Redux Thunk を使ってかく。

src/actions/index.js
export const CONCAT_HOGE_SUCCESS = "CONCAT_HOGE_SUCCESS"
export const CONCAT_HOGE_FAIL = "CONCAT_HOGE_FAIL"

export const concatHoge = (offset) => {
  return (dispatch) => {
    axis({
      url: "http://hoge-api.com/hoges?offet=" + offset,
      method: "POST"
    }).then((response) => {
      let response_status = response["data"]["status"]
      if (response_status == "ok"){
        let response_data = response["data"]["hoge"]
        dispatch(concatHogeSuccess(response_data))
      } else {
        dispatch(concatHogeFail())
      }
    })
  }
}

const concatHogeSuccess = (data) => {
  return{
    type: CONCAT_HOGE_SUCCESS,
    data: data,
  }
}

const concatHogeFail = () => {
  return {
    type: CONCAT_HOGE_FAIL,
  }
}

src/reducers/hoge.js
import {CONCAT_HOGE_SUCCESS, CONCAT_HOGE_FAIL} from "../actions";

export const hoge = (state=[], action) => {
  switch(action.type){
  // ... 省略
    case CONCAT_HOGE_SUCCESS:
      return [...state, ...action.data]
    case CONCAT_HOGE_FAIL:
      return state
  }
}

これで、下のようなReactのコードで、ボタンを押せば、パージネーション の続きが見れるようになる。

src/hoge.js
import {useState, useRef} from "react"
import {useDispatch, useSelector} from "react-redux"
// ... 省略
const hoge = () => {
  const dispatch = useDispatch()
  const hoge = useSelector(state => state.hoge)
  // setTimeout 用 の state
  const [offset, setOffset] = useState(2) /* API の URL に合わせる */
  const offsetRef = useRef(offset)
  offsetRef.current = offset
  // ... 省略
  const onClickHogeOffset = () => {
    dispatch(offset)
    let next_offset = offset + 1
    setOffset(next_offset)
  }
  return {
   <> 
     {hoge.map((item) => {
        // ... 省略
      })}
      <div className="pagination-next-area">
        <button onClick={() => onClickHogeOffset()}>
          もっと見る
        </button>
      </div>
    </>
  }
}

React

javascript の event の scroll を使う。
上の Reactのファイル に、まず useEffect で 初期のスクロール位置を取得し、window に onScrollPagination イベントを追加します。

src/hoge.js
import {useState, useRef, useEffect} from "react"
// ... 省略
const hoge = () => {
// ... 省略
  const [paginationPos, setPaginationPos] = useState(0)
  const paginationPosRef = useRef(paginationPos)
  paginationPosRef.current = paginationPos
// ... 省略
  useEffect(() => {
    window.setTimeout(initializePagination, 1000) /* 描画が遅れる問題 */
  })
// ... 省略
  const initializePagination = () => {
    var pagination_area = document.getElementsByClassName("pagination-next-area")[0]
    setPaginationPos(pagination_area.offsetTop)
    window.addEventListener("scroll", onScrollPagination)
  }
  const onScrollPagination = () => {
    // ここに scroll イベントを実装する
  }
}

window の位置が、上記の paginationPos を越した場合に、上記の dispatch(concatHoge(offset)) を含んだ onClickHogeOffset を発火させる。

src/hoge.js
import concatHoge from "./actions"
// ... 省略
  const onScrollPagination = () => {
    if (window.scrollY + window.innerHeight > paginationPosRef.current ) {
      onClickHogeOffset()
      var pagination_area = document.getElementsByClassName("pagination-next-area")[0]
      pagination_area.removeEvent("scroll", onScrollPagination)
      // PaginationPos を更新する
      setPaginationPos(pagination_area.offsetTop)
      window.addEventListener("scroll", onScrollPagination)
    }
  }

以上でした。

0
0
0

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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?