useQueryのonSuccess内の処理を分岐したいです
解決したいこと
ページングのために、
「次へ」ボタン(PC用)
「次のデータを見る」ボタン(スマホ用)
を設置したいと思っています。
外部データの取得にあたっては、useQueryを使用し、
「次へ」ボタンをクリックしたときは、取得したデータをitemsに上書きし、
「次のデータを見る」ボタンをクリックしたときは、itemsに累積追加し、
それを、ブラウザーに表示したいと考えています。
一応、flagというstateを作って、
「次へ」ボタンをクリックしたとき、setFlag(1)
「次のデータを見る」ボタンをクリックしたとき、setFlag(2)として、
onSuccess内において、flagの値で条件分岐させると、
一見それらしく動くのですが、早く何回もクリックすると、挙動がおかしくなります。
そこで、
const flg; というパラメータを設定して、
こちらを条件分岐に使いたいと思うのですが、onSuccess内に渡すことができません。
何か良い方法はないでしょうか?
[サイト] https://willowy-pixie-73a101.netlify.app/
コード
import styles from "../styles/Home.module.css";
import { useState } from "react";
import { useQuery } from "react-query";
import { QueryClient, QueryClientProvider } from "react-query";
const queryClient = new QueryClient({
defaultOptions: {
queries: {
retry: false,
refetchOnWindowFocus: false,
},
},
});
export default function Home() {
return (
<QueryClientProvider client={queryClient}>
<Main />
</QueryClientProvider>
);
}
function Main() {
const [page, setPage] = useState(1); //現在のページ
const [items, setItems] = useState([]); //アイテムの配列
const [pageCount, setPageCount] = useState(""); //総ページ数
const [flag, setFlag] = useState(1);
const options = {
params: {
page: page,
},
};
let flg = 1;
const {
data: data1,
isLoading: isLoading1,
isError: isError1,
error: error1,
refetch: refetch1,
} = useQuery(
["items1"],
async () => {
const urlSearchParam = new URLSearchParams(options.params).toString();
const defaultEndpoint = "/api/items?" + urlSearchParam;
return await fetch(defaultEndpoint).then((res) => res.json());
},
{
enabled: true,
onSuccess: (data1) => {
if (flg == 1) { // constを使用
// if (flag == 1) { // stateを使用
setItems(data1.users.items); //データを上書きセット
} else {
setItems((prev) => { //データを累積セット
return [...prev, ...data1.users.items];
});
}
setPageCount(data1.users.pageCount);
},
}
);
if (isLoading1) return <span>Loading...</span>;
if (isError1) return <span>Error:{error1.message}</span>;
const getItems = async () => {
refetch1();
};
// Pagination +
const pageIncrement = () => {
if (page < pageCount) {
const newPage = page + 1;
setPage((prevPage) => prevPage + 1);
options.params.page = newPage;
flg = 1;
setFlag(1);
getItems();
}
};
// Readmore +
const pageReadmore = () => {
if (page < pageCount) {
const newPage = page + 1;
setPage((prevPage) => prevPage + 1);
options.params.page = newPage;
flg = 2;
setFlag(2);
getItems();
}
};
return (
<>
{items.map((item, index) => {
<div key=(index)>
{item}
</div>
}
//レスポンシブデザイン CSSで片方のみ表示させる
//PC用のボタン
<button className={styles.nextButton} onClick={() => pageIncrement()}>次へ</button>
//スマホ用のボタン
<button className={styles.readMoreButton} onClick={pageReadmore}>次のデータを見る</button>
</>
);
}
/* PC設定 */
.readMoreButton {
display: none;
}
/* タブレット設定 */
@media screen and (max-width: 800px) {
.nextButton {
display: none;
}
.readMoreButton {
display: block;
}
}