質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Firebase

Firebaseは、Googleが提供するBasSサービスの一つ。リアルタイム通知可能、並びにアクセス制御ができるオブジェクトデータベース機能を備えます。さらに認証機能、アプリケーションのログ解析機能などの利用も可能です。

Redux

Reduxは、JavaScriptアプリケーションの状態を管理するためのオープンソースライブラリです。ReactやAngularで一般的にユーザーインターフェイスの構築に利用されます。

Next.js

Next.jsは、Reactを用いたサーバサイドレンダリングなどを行う軽量なフレームワークです。Zeit社が開発しており、nextコマンドでプロジェクトを作成することにより、開発環境整備が整った環境が即時に作成できます。

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

Q&A

解決済

1回答

1020閲覧

Next.js Redux-toolkit Immer Error について

daaaiki

総合スコア4

Firebase

Firebaseは、Googleが提供するBasSサービスの一つ。リアルタイム通知可能、並びにアクセス制御ができるオブジェクトデータベース機能を備えます。さらに認証機能、アプリケーションのログ解析機能などの利用も可能です。

Redux

Reduxは、JavaScriptアプリケーションの状態を管理するためのオープンソースライブラリです。ReactやAngularで一般的にユーザーインターフェイスの構築に利用されます。

Next.js

Next.jsは、Reactを用いたサーバサイドレンダリングなどを行う軽量なフレームワークです。Zeit社が開発しており、nextコマンドでプロジェクトを作成することにより、開発環境整備が整った環境が即時に作成できます。

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

0グッド

0クリップ

投稿2021/06/24 02:33

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;

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

userSliceの変更

import { createSlice, PayloadAction } from "@reduxjs/toolkit"; import { RootState } from "../app/store"; type USER = { displayName: string; photoUrl: string; }; const userSlice = createSlice({ ... ... reducers: { login: (state, action) => (state.user = action.payload), ↓              ↓   login: (state,action)=>{state.user=action.payload} ... ... }); export const { login, logout, signUpUserProfile, updateUserProfile } = userSlice.actions; export const selectUser = (state: RootState) => state.user.user; export default userSlice.reducer;

シンプルに構文ミスでした

voidの関数にしなければならないのを書き方が違い、anyを返すものになってしまっていました。

投稿2021/06/25 02:00

daaaiki

総合スコア4

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問