Nextを使用してアプリを作っているのですが、ページのレンダリングごとに
このようなエラーが出ます。
redux-toolkitのimmerについてのエラーだと思いimmerについて調べながらコードを見返してみてもまったくわかりませんでした。
_app.tsx
import React, { useEffect } from "react"; import "../../styles/globals.css"; import { Provider, useDispatch } from "react-redux"; import { store } from "../app/store"; import { login, logout } from "../features/userSlice"; import { auth } from "../firebase"; function MyApp({ Component, pageProps }) { const AuthComponent = React.memo(() => { const dispatch = useDispatch(); // to check firebase auth state useEffect(() => { const unsubscribe = auth.onAuthStateChanged((authUser) => { if (authUser) { dispatch( login({ uid: authUser.uid, photoUrl: authUser.photoURL, displayName: authUser.displayName, }) ); } }); // cleanup return () => unsubscribe(); }, []); return null; }); return ( <Provider store={store}> <AuthComponent /> <Component {...pageProps} /> </Provider> ); } export default MyApp;
Layout.tsx
import Head from "next/head"; import Link from "next/link"; import { useSelector } from "react-redux"; import { selectUser } from "../features/userSlice"; type TITLE = { title: string; }; const Layout: React.FC<TITLE> = ({ children, title = "nextjs" }) => { const userData = useSelector(selectUser); return ( <div> <Head> <title>{title}</title> </Head> <header> <Link href="/home"> <div>icon</div> </Link> <div>menu</div> <div className="menu-list"> {userData.uid ? ( <> <Link href="/user">USER</Link> <Link href="/home">HOME</Link> </> ) : ( <> <Link href="/authentication">AUTH</Link> </> )} </div> </header> <main>{children}</main> <footer></footer> </div> ); }; export default Layout;
store.tsx
import { configureStore, ThunkAction, Action } from "@reduxjs/toolkit"; import userReducer from "../features/userSlice"; import roomReducer from "../features/roomSlice"; import statusReducer from "../features/statusSlice"; export const store = configureStore({ reducer: { user: userReducer, room: roomReducer, status: statusReducer, }, }); export type RootState = ReturnType<typeof store.getState>; export type AppThunk<ReturnType = void> = ThunkAction< ReturnType, RootState, unknown, Action<string> >;
userSlice.tsx
import { createSlice, PayloadAction } from "@reduxjs/toolkit"; import { RootState } from "../app/store"; type USER = { displayName: string; photoUrl: string; }; const userSlice = createSlice({ name: "user", initialState: { user: { uid: "", displayName: "", photoUrl: "" } }, reducers: { login: (state, action) => (state.user = action.payload), logout: (state) => { state.user = { uid: "", displayName: "", photoUrl: "" }; }, signUpUserProfile: (state, action) => (state.user.displayName = action.payload.displayName), updateUserProfile: (state, action: PayloadAction<USER>) => { state.user.displayName = action.payload.displayName; state.user.photoUrl = action.payload.photoUrl; }, }, }); export const { login, logout, signUpUserProfile, updateUserProfile } = userSlice.actions; export const selectUser = (state: RootState) => state.user.user; export default userSlice.reducer;
statusSlice.tsx
import { createSlice } from "@reduxjs/toolkit"; const statusSlice = createSlice({ name: "status", initialState: { status: { LoL: { platform: "", id: "", level: "", rank: "" }, Valorant: { platform: "", id: "", level: "", rank: "" }, Apex: { platform: "", id: "", level: "", rank: "" }, Fortnite: { platform: "", id: "", level: "", rank: "" }, }, }, reducers: { setStatus: (state, action) => (state.status = action.payload), }, }); export const { setStatus } = statusSlice.actions; export const selectStatus = (state) => state.status.status; export default statusSlice.reducer;
roomSlice.tsx
import { createSlice, PayloadAction } from "@reduxjs/toolkit"; const roomSlice = createSlice({ name: "room", initialState: { room: { title: "", roomId: "", member: "", host: false }, }, reducers: { reqruit: (state, action) => { state.room = { title: action.payload.title, roomId: action.payload.roomId, member: action.payload.member, host: true, }; }, join: (state, action) => { state.room = { title: action.payload.title, roomId: action.payload.roomId, member: action.payload.member, host: false, }; }, }, }); export const { reqruit, join } = roomSlice.actions; export const selectRoom = (state) => state.room.room; export default roomSlice.reducer;
authentication.tsx
import { useState } from "react"; import { useForm } from "react-hook-form"; import { useDispatch, useSelector } from "react-redux"; import { auth, db } from "../firebase"; import router from "next/router"; import { selectUser, signUpUserProfile } from "../features/userSlice"; import { setStatus } from "../features/statusSlice"; import { getStatus } from "../gameapi"; import Layout from "../components/Layout"; const authentication = () => { const [isLogin, setIsLogin] = useState(true); const { register, handleSubmit } = useForm(); const dispatch = useDispatch(); const user = useSelector(selectUser); const authSignIn = async (e) => { const userData = await auth.signInWithEmailAndPassword(e.email, e.password); const docRef = db.collection("status").doc(`${userData.user.displayName}`); const doc = await docRef.get(); //アカウントが保存している{title:{platform:"",id:""}...}をとり if (doc.exists) { const data = ""; Object.keys(doc.data()).map((title) => { data[title] = getStatus( title, doc.data()[title].platform, doc.data()[title].id ); }); dispatch(setStatus(data)); } else { alert("ゲームアカウントを設定して下さい。"); router.push("/user"); } }; const authSignUp = async (e) => { const authUser = await auth.createUserWithEmailAndPassword( e.email, e.password ); authUser.user?.updateProfile({ displayName: e.username, }); dispatch( signUpUserProfile({ displayName: e.username, }) ); }; return ( <Layout title="auth"> <div className="auth-wrapper"> <form className="auth-form" onSubmit={ isLogin ? handleSubmit(authSignIn) : handleSubmit(authSignUp) } > {isLogin ? ( <> <label> email <input {...register("email")} /> </label> <label> password <input type="password" {...register("password")} /> </label> </> ) : ( <> <label> username <input {...register("displayName")} /> </label> <label> email <input {...register("email")} /> </label> <label> password <input type="password" {...register("password")} /> </label> </> )} <button>{isLogin ? "Login" : "Signup"}</button> </form> {isLogin ? ( <button onClick={() => setIsLogin(false)}>アカウント作成へ</button> ) : ( <button onClick={() => setIsLogin(true)}> アカウントをお持ちの方 </button> )} </div> </Layout> ); }; export default authentication;
index.tsx
import Layout from "../components/Layout"; const index: React.FC = () => { return ( <Layout title="index"> <p className="text-4xl">Welcome to Nextjs</p> </Layout> ); }; export default index;
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。