ログインしたユーザーが、ニックネームとアバター写真を変更した時、useSWR()関数を使って、すぐにブラウザに反映したいです
useSWR()関数にアクセストークンを付けて、fetchする方法がわかりません。
/components/ProfileForm.js
モーダルにて、フォームを開き、ログインしたユーザーのニックネームとアバター写真を変更するコードを書いたファイルの内容
/components/ProfileForm.js
import axios from "axios";
import { apiUrlPart } from "../config";
import { useContext } from "react";
import { StateContext } from "../context/StateContext";
import { useSession } from "next-auth/client";
import Modal from "react-modal";
import { Button, TextField, IconButton } from "@material-ui/core";
import { FcCamera } from "react-icons/fc";
const customStyles = {
overlay: {
position: "fixed",
top: 0,
left: 0,
backgroundColor: "rgba(0,0,0,0.3)",
},
content: {
top: "50%",
left: "50%",
width: "500px",
height: "300px",
transform: "translate(-50%, -50%)",
},
};
Modal.setAppElement("#__next");
export default function PostForm({ profileEdited }) {
const [session] = useSession();
const {
nickName,
setNickName,
avatar,
setAvatar,
openProfileModal,
setOpenProfileModal,
} = useContext(StateContext);
const update = async (e) => {
e.preventDefault();
const uploadData = new FormData();
uploadData.append("nickname", nickName);
uploadData.append("avatar", avatar, avatar.name);
try {
const res = await axios.patch(
`${apiUrlPart}/api/social/login/users/${session.userId}/`,
uploadData,
{
headers: {
"Content-Type": "application/json",
Authorization: `JWT ${session.accessToken}`,
},
}
);
setOpenProfileModal(false);
profileEdited();
} catch {
console.log("error");
}
};
const handlerAvatar = () => {
const fileInput = document.getElementById("avatarInput");
fileInput?.click();
};
return (
<div>
<div
className="inline-block mr-8 hover:bg-indigo-600 text-white px-3 py-3 rounded cursor-pointer"
onClick={() => setOpenProfileModal(true)}
>
<img className="rounded-full object-cover h-24" src={session.avatar} />
<p>{session.nickName}</p>
</div>
<Modal
isOpen={openProfileModal}
onRequestClose={() => setOpenProfileModal(false)}
style={customStyles}
>
<form>
<div>
<TextField
placeholder="Please edit your username"
type="text"
onChange={(e) => setNickName(e.target.value)}
/>
</div>
<br />
<div>
<input
type="file"
id="avatarInput"
hidden={true}
onChange={(e) => setAvatar(e.target.files[0])}
/>
<IconButton onClick={handlerAvatar}>
<FcCamera />
</IconButton>
</div>
<br />
<Button
disabled={!nickName || !avatar}
variant="contained"
color="primary"
onClick={update}
>
Edit Profile
</Button>
</form>
</Modal>
</div>
);
}
以下、Client Side Fetching用のuseSWR()関数を使っているファイルの内容
/components/ProfileOperation.js
import { getUserData } from "../lib/profile";
import { apiUrlPart } from "../config";
import ProfileForm from "./ProfileForm";
// Client Side Data Fetching
import { useEffect } from "react";
import useSWR from "swr";
import { useSession } from "next-auth/client";
// Client Side Data Fetching
const fetcher = (url) => fetch(url).then((res) => res.json());
const apiUrl = `${apiUrlPart}/api/social/login/user/`;
export default function Home({ user }) {
const [session] = useSession();
// Client Side Data Fetching
//==========================================================================
// この部分をどのように書けばいいのか、わかりません。
const config = {
headers: {
Authorization: `JWT ${session.accessToken}`,
},
};
const { data: user2, mutate } = useSWR([apiUrl, config], fetcher, {
fallbackData: user,
});
//==========================================================================
useEffect(() => {
mutate();
}, []);
console.log(user2);
return (
<div>
<ProfileForm profileEdited={mutate} />
</div>
);
}
export async function getStaticProps() {
const user = await getUserData();
return {
props: { user },
revalidate: 1, // ISR (Increment Static Regeneration) を有効にする
};
}
以下、SSG (Static Site Generation) のgetStaticProps()関数内にて呼び込む関数を書いたファイルの内容
/lib/profile.js
import { apiUrlPart } from "../config";
import { useSession } from "next-auth/client";
export async function getUsersData() {
const [session] = useSession();
const apiRes = await fetch(`${apiUrlPart}/api/social/login/user/`, {
method: "GET",
headers: {
Authorization: `JWT ${session.accessToken}`,
},
});
const data = await apiRes.json();
// console.log(data.user);
user = data.user;
return user;
}
上記のファイルを連動させて、Client Side Data Fetchingを実行しようとしましたが、「認証情報がない」とエラーが出てしまいます。
アクセストークンを付けて、APIにリクエストできていないようです。
ご教授お願いしたいです。
useSWR() を使わない(すぐにブラウザに反映されない)でよいのなら、きちんとプロフィール情報の変更は動いています。
useSWRを使わずに、useEffect内で、プロフィールに変更があったら再度プロフィール情報をGETする処理をしてみてはいかがでしょうか。
なるほど、そうですね。
難しいことをやろうとしていました。
useEffectを試してみます。
ありがとうございます!