NextJs + Redux:错误:无法读取null的属性(阅读“useContext”)

n1bvdmb6  于 2023-10-19  发布在  其他
关注(0)|答案(1)|浏览(160)

我是新的下一个和redux,我怎么有问题

如上所示是错误时,尝试选择redux值存储.
我试过使用Redux Toolkit的原始用户名也返回相同的错误。
尝试了许多方法安装和重新安装也同样的错误返回。这种情况下怎么办呢?
redux reducer / slices:

import { createSlice, PayloadAction } from '@reduxjs/toolkit';

type InitialState = {
    value: AuthState;
}

type AuthState = {
    isAuth: boolean,
    username: string,
    uid: string,
    isModerator: boolean,
}

const initialState = {
    value: {
        isAuth: false,
        username: "",
        uid: "",
        isModerator: false,
    },
} as InitialState;

export const auth = createSlice({
    name: 'auth',
    initialState,
    reducers: {
        logOut: () => {
            return initialState;
        },
        logIn: (state, action: PayloadAction<string>) => {
            return {
                value: {
                    isAuth: true,
                    username: action.payload,
                    uid: "can update later",
                    isModerator: false,
                },
            };
        },
    },
});

export const { logIn, logOut } = auth.actions;
export default auth.reducer;

商店

import { configureStore } from '@reduxjs/toolkit';
import authReducer from './features/auth-slice';
import { TypedUseSelectorHook, useSelector } from 'react-redux';

export const store = configureStore({
    reducer: {
        auth: authReducer,
    },
});

/** Infer the `RootState` and `AppDispatch` types from the store itself */
export type RootState = ReturnType<typeof store.getState>;
/** Inferred type: {posts: PostsState, comments: CommentsState, users: UsersState} */
export type AppDispatch = typeof store.dispatch;

export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;

登录页面:

'use client';
import React, {useCallback, useEffect, useState} from 'react';
import styles from './login.module.css';
import { useRouter } from 'next/navigation';
import { useDispatch } from 'react-redux';
import { logIn, logOut } from '@/redux/features/auth-slice';

const Login = () => {
  const router = useRouter();
  const [username, setUsername] = useState('');
  const [password, setPassword] = useState('');
  const [error, setError] = useState('');

  const dispatch = useDispatch();

  
  function login() {
    /** validate credential of user */
    if (!username && !password) {
      setError('Username and Password is required');
      return;
    } else if (username.length <= 0 && password.length <= 0) {
      setError('Username and Password is required');
      return;
    } else if (username.length <= 0) {
      setError('Username is required');
      return;
    } else if (password.length <= 0) {
      setError('Password is required');
      return;
    } else {
      setError('');
    }

    /**
     * Run Validation with APIs here to check with the backend.
     * since this is POC Project with only front end, leave this part
     * and can continue later on if want to add
     * in the meantime, bypass this authentication
    * */
    dispatch(logIn(username));
    router.push('/users');
  };
  
  const LoginError = (props: any) => {
    return (
      <div className="alert alert-error">
        <svg xmlns="http://www.w3.org/2000/svg" className="stroke-current shrink-0 h-6 w-6" fill="none" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z" /></svg>
        <span>{error}</span>
      </div>
    );
  };

  return (
    <div className={styles.mainContainer}>
      <div className="grid place-content-center pt-40">
        <h1 className="text-5xl text-violet-500">
          <i>Developer Membership System</i>
        </h1>
        <h2 className="text-xl text-violet-300">
          By Highrul.dev | next.js
        </h2>
        <div className="flex items-center justify-center h-full pt-20">
          <input
            type="text"
            placeholder="Username"
            className="input input-bordered input-primary w-full max-w-xs"
            onChange={(e) => setUsername(e.target.value)}
          />
        </div>
        <div className="flex items-center justify-center h-full pt-4">
          <input
            type="password"
            placeholder="Password"
            className="input input-bordered input-primary w-full max-w-xs"
            onChange={(e) => setPassword(e.target.value)}
          />
        </div>
        <div className="flex items-center justify-center h-full pt-4">
          <button onClick={login} className="btn btn-primary w-full max-w-xs">Login</button>
        </div>
        <div className="flex items-center justify-center h-full pt-4">
          {error && <LoginError />}
        </div>
      </div>
    </div>
  )
};

export default Login;

和用户页来测试选择器:

import { useAppSelector } from '@/redux/store';
import React from 'react'

interface User {
    id: number;
    name: string;
    username: string;
    email: string;
};

const UsersPage = async () => {
    const username = useAppSelector((state) => state.auth.value.username);
    // const currentUser = useSelector(credential);
    const res = await fetch(
        'https://jsonplaceholder.typicode.com/users',
        { next: { revalidate: 10 } }
    );
    const users: User[] = await res.json();
  return (
    <>
    {{username}}
     <h1>Users</h1>
     {/* <table className="table table-bordered">
        <thead>
            <th>
                Name | Username
            </th>
            <th>
                Email
            </th>
        </thead>
        { users.map(user => 
            <tr key={user.id}>
                <td>{user.name} | @{user.username}</td>
                <td>{user.email}</td>
            </tr>
        )}
     </table> */}
    </>
  )
}

export default UsersPage

哪一部分设置错误?

ohfgkhjo

ohfgkhjo1#

像下面这样更新你的代码,看看。
redux reducer / slices:

// actions
export const { logIn, logOut } = auth.actions;

// selectors
export const getUserName  = (state: RootState) => state.auth.value.username;

export default auth.reducer;

和用户页来测试选择器:

const username = useAppSelector(getUserName);

相关问题