+GraphQL-無限スクロールのTypescriptを作成
無限スクロールをしたいです。
https://velog.io/@mkh1213/React-GraphQL-Typescript-%EC%8B%9C%EC%9E%91%ED%95%98%EA%B8%B0-4
ログインページ
import React from "react";
import { BrowserRouter , Route, Routes } from "react-router-dom";
import Navigation from "./components/Navigation";
import Home from "./pages/Home";
import Modify from "./pages/Modify";
import SignUp from "./pages/SignUp";
import Study from "./pages/Study";
import InfinityScroll from "./pages/InfinityScroll";
function Router() {
return (
<BrowserRouter >
<Navigation />
<br />
<Routes>
<Route path="/" element={<Home />} />
<Route path="/signup" element={<SignUp />} />
<Route path="/modify" element={<Modify />} />
<Route path="/study" element={<Study />} />
<Route path="/InfinityScroll" element={<InfinityScroll />} />
</Routes>
</BrowserRouter >
);
}
export default Router;
import React from "react";
import { Link } from "react-router-dom";
import Box from '@mui/material/Box';
import Button from '@mui/material/Button';
import { useCookies } from "react-cookie";
function Navigation() {
const [cookies] = useCookies(['test']);
return (
<div className="nav">
<Box sx={{ display: 'flex', alignItems: 'center', textAlign: 'center' }}>
<Button>
<Link to="/" style={{ textDecoration: 'none', color: '#1976d2' }}>Home</Link>
</Button>
<Button style={cookies.test === undefined ? {display: 'none'} : {display: ''}}>
<Link to="/modify" style={{ textDecoration: 'none', color: '#1976d2' }}>Modify</Link>
</Button>
<Button>
<Link to="/study" style={{ textDecoration: 'none', color: '#1976d2' }}>Study</Link>
</Button>
<Button>
<Link to="/InfinityScroll" style={{ textDecoration: 'none', color: '#1976d2' }}>InfinityScroll</Link>
</Button>
</Box>
</div>
);
}
export default Navigation;
import React, { useCallback, useEffect, useState } from "react";
import { GET_USERS_INIT, GET_USERS } from "../gql/InfinityScroll.gql";
import { useLazyQuery } from "@apollo/client";
import UserList from "../components/UserList";
function InfinityScroll() {
const [users, setUsers] = useState<any>([]);
const [lastId, setLastId] = useState("");
const [isUsersLoading, setIsUsersLoading] = useState<boolean>(false);
const [isExistMore, setIsExistMore] = useState<boolean>(true);
const [getUsersInit, {loading, error}] = useLazyQuery(GET_USERS_INIT, {
fetchPolicy: "cache-and-network",
onError: error => {
console.error(error);
alert(error.message);
},
onCompleted: ({getUsersInit}) => {
setUsers(getUsersInit);
setLastId(getUsersInit[getUsersInit.length - 1]._id);
}
});
const [getUsers, {loading: loading2, error: error2}] = useLazyQuery(GET_USERS, {
fetchPolicy: "cache-and-network",
onError: error => {
console.error(JSON.stringify(error, null, 2))
alert(error.message);
},
onCompleted: ({getUsers}) => {
if (getUsers.length < 20) setIsExistMore(false);
setIsUsersLoading(false);
setLastId(getUsers[getUsers.length - 1]._id);
setUsers([...users, ...getUsers]);
}
});
const handleScroll = useCallback((): void => {
const { innerHeight } = window;
// 브라우저창 내용의 크기 (스크롤을 포함하지 않음)
const { scrollHeight } = document.body;
// 브라우저 총 내용의 크기 (스크롤을 포함한다)
const { scrollTop } = document.documentElement;
// 현재 스크롤바의 위치
if (Math.round(scrollTop + innerHeight) >= scrollHeight) {
// scrollTop과 innerHeight를 더한 값이 scrollHeight보다 크다면, 가장 아래에 도달했다는 의미이다.
if (isExistMore) {
setIsUsersLoading(true);
getUsers({ variables: { lastId } });
}
}
}, [lastId]);
useEffect(() => {
getUsersInit()
}, []);
useEffect(() => {
window.addEventListener('scroll', handleScroll, true);
// 스크롤이 발생할때마다 handleScroll 함수를 호출하도록 추가합니다.
return () => {
window.removeEventListener('scroll', handleScroll, true);
// 해당 컴포넌트가 언마운트 될때, 스크롤 이벤트를 제거합니다.
};
}, [handleScroll]);
return (
<div>
<UserList userData={users} />
</div>
);
}
export default InfinityScroll;
データの構成はid、email、nameであり、idはmongodbが自動的に生成する数値であり、idにはタイムスタンプ値が含まれているため、20データの最後の値をサーバに渡して次の20データを取得することができる.
UserListの作成
import React from "react";
import UserInfo from "./UserInfo";
function UserList({userData}: any) {
return (
<div>
{userData.map((user: any) => (
<UserInfo
key={user._id}
_id={user._id}
email={user.email}
name={user.name}
/>
))}
</div>
)
}
export default UserList;
作成import React from "react";
function UserInfo({_id, email, name}: any) {
return (
<div>
<div style={{border: "1px solid grey", borderRadius: 10, padding: 10, margin: 10}}>
<p>_id: {_id}</p>
<p>email: {email}</p>
<p>name: {name}</p>
</div>
</div>
)
}
export default UserInfo;
import gql from 'graphql-tag';
export const GET_USERS_INIT = gql`
query getUsersInit {
getUsersInit {
_id
email
name
}
}
`
export const GET_USERS = gql`
query getUsers($lastId: String!) {
getUsers(lastId: $lastId) {
_id
email
name
}
}
`
実装結果
サーバコードを作成...
勉強して...
Reference
この問題について(+GraphQL-無限スクロールのTypescriptを作成), 我々は、より多くの情報をここで見つけました https://velog.io/@mkh1213/React로-무한-스크롤-만들기テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol