ログインしたユーザーが、ニックネームとアバター写真を変更した時、useSWR()関数を使って、すぐにブラウザに反映したいです
解決済
回答 2
2022/02/25 16:26
質問内容

実現したいこと

ログインしたユーザーが、ニックネームとアバター写真を変更した時、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() を使わない(すぐにブラウザに反映されない)でよいのなら、きちんとプロフィール情報の変更は動いています。

回答 2
ベストアンサーを選択すると、解決済みとなります。
nodata
まだ回答がありません
回答
nodata
回答するにはログインが必要です