繁体   English   中英

错误:找不到 react-redux 上下文值; 请确保组件被包裹在一个<Provider>在使用 useselector 时

[英]Error: could not find react-redux context value; please ensure the component is wrapped in a <Provider> while using useselector

1.header.js

import Image from "next/image";
import { 
MenuIcon,
SearchIcon,
ShoppingCartIcon,
} from "@heroicons/react/outline";
import { signIn, signOut, useSession } from "next-auth/react";
import { useRouter } from "next/router";
import { useSelector } from "react-redux";
import { selectItems } from "../slices/basketSlice";
import { Provider } from "react-redux";

function Header() {
const { data: session } = useSession();
const router = useRouter();
const items= useSelector(selectItems);

 return (
<header>
   <div className="flex items-center bg-amazon_blue p-1 flex-grow py-2">
     <div className="mt-2 flex items-center flex-grow sm:flex-grow-0">
      <Image
      onClick={() => router.push("/")} 
        src='https://links.papareact.com/f90'
        width={150}
        height={40}
        objectFit="contain"
        className="cursor-pointer"
      />
     </div>
     {/*search bar*/}
     <div className="hidden sm:flex items-center h-10 rounded-md flex-grow cursor-pointer bg-yellow-400 hover:bg-yellow-500">
       <input className="p-2 h-full w-6 flex-grow flex-shrink rounded-l-md focus:outline-none px-4" type="text" />
       <SearchIcon className="h-12 p-4"/>
     </div>
     <div className="text-white flex items-center text-xs space-x-6 mx-6 whitespace-nowrap">
       <div onClick={session ? signIn:signOut} className="link">
         <p className="hover:underline">{session ? session.user.name:"signin"}</p>
         <p  className="font-extrabold md:text-sm">Acount & lists</p>
       </div>

       <div className=" link">
         <p>Returns</p>
         <p className="font-extrabold md:text-sm">& orders</p>
       </div>
       
       <div onClick={() => router.push("/checkout")} className=" link relative flex items-center">
         <span className="absolute top-0 right-0 md:right-10 h-4 w-4 bg-yellow-400 rounded-full text-center text-black font-bold">
           {items.length}
         </span>

       <ShoppingCartIcon className="h-10 "/>
       <p className="hidden md:inline font-extrabold md:text-sm mt-2">Bascket</p>
       </div>
     </div>
  </div>
     {/*bottom nav*/}
  <div className="flex items-center space-x-3 p-2 pl-6 bg-amazon_blue-light text-white text-sm">
    <p  className="link flex items-center ">
      <MenuIcon className="h-6 mr-5"/>
      all</p>
      <p className="link">featured </p>
      <p className="link">new arrival </p>
      <p className="link">catalog </p>
      <p className="link hidden lg-inline-flex">electronics </p>
  </div>
</header>
   );
}

export default Header;
  1. 篮子切片.js

'''

import { createSlice } from "@reduxjs/toolkit";

const initialState = {
  items: [],
};

export const basketSlice = createSlice({
  name: "basket",
  initialState,
  reducers: {
    addToBasket: (state, action) => {
      state.items = [...state.items, action.payload]
    },
    removeFromBasket: (state, action) => {},
  },
});

export const { addToBasket, removeFromBasket } = basketSlice.actions;

// Selectors - This is how we pull information from the Global store slice
export const selectItems = (state) => state.basket.items;

export default basketSlice.reducer;

'''

  1. 产品.js

    '''

    从“下一个/图像”导入图像; 从“反应”导入 {useState}; 从“@heroicons/react/solid”导入{ StarIcon}; 从“react-currency-format”导入货币; 从“react-redux”导入 { useDispatch }; 从“../slices/basketSlice”导入{addToBasket};

    常量 MAX_RATING =5; 常量 MIN_RATING =1;

     function Product({id, title, price, description, category,image}) { const dispatch = useDispatch(); const{rating}= useState( Math.floor(Math.random() * (MAX_RATING - MIN_RATING +1)) + MIN_RATING ); const addItemToBascket = () => { const product = {id, title, price, description, category,image}; // sending the product as an action to bascket slice dispatch(addToBasket(product)) };

    返回({类别}

     <Image src={image} height={200} width={200} objectFit="contain" /> <h4 className="flex">{title}</h4> <div className="flex"> {Array(rating) .fill() .map((_, i)=>( <StarIcon className="h-5 text-yellow-500"/> ))} </div> <p className="text-xs my-2 line-clamp-2">{description}</p> <div className="mb-5"> <Currency quantity={price}/> </div> <button onClick={addItemToBascket} className=" mt-auto button">Add to Basket</button> </div>

    ); }

    导出默认产品'''

store.js

import { configureStore } from "@reduxjs/toolkit";
import basketReducer from "../slices/basketSlice";

export const store = configureStore({
  reducer: {
    basket: basketReducer,
  },
});

_app.js

import { Provider } from 'react-redux'
import { store } from '../app/store'
import '../styles/globals.css'
import { SessionProvider } from "next-auth/react"

const MyApp = ({ Component, pageProps: {session,...pageProps} }) => {
  return (
    <SessionProvider session={session}>
        <Component {...pageProps} />
    </SessionProvider>
  );
};

export default MyApp

我的代码中的文件

我如何在代码中使用提供程序

我的存储库:- https://github.com/Shadow2389/nmz-2.git

看来我们都是桑尼的粉丝。 您的问题是您需要将 App.js 包装在

<Provider>
 <SessionProvider session={session}>
        <Component {...pageProps} />
    </SessionProvider>
</Provider>

但是你很可能会遇到“水合错误”,如果是这样,只需删除"Math.floor(Math.random() * (MAX_RATING - MIN_RATING +1)) + MIN_RATING"

显然,随着新的更新,我们不能再像以前那样使用 useState() 钩子了,所以你有 3 个选项: 1.- 删除"Math.floor(Math.random() * (MAX_RATING - MIN_RATING +1)) + MIN_RATING" 2.- 为所有产品设置固定评级 3.- 为您的 API 设置一个数字(因为您使用的是 FakeStoreAPI,所以您不能这样做)

这是由于 Hooks 的基本规则,因为随机数是“不可预测的”,但现在我不知道它为什么会出现这个问题(尽管您正在设置最小值和最大值)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM