StateProvider返回给我的迭代未定义



StateProvider.js

import React, { createContext, useContext, useReducer } from "react";
// Prepares the dataLayer
export const StateContext = createContext();
// Wrap our app and provide the Data layer
export const StateProvider = ({ reducer, initialState, children }) => (
<StateContext.Provider value={useReducer(reducer, initialState)}>
{children}
</StateContext.Provider>
);
// Pull information from the data layer
export const useStateValue = () => useContext(StateContext);

Reducer.js

export const initialState = {
basket: [],
};
const reducer = (state, action) => {
console.log(action);
switch (action.type) {
case "ADD_TO_BASKET":
return {
...state,
basket: [**your text**...state.basket, action.item],
};
}
}
export default reducer;

Proudct.js

import React from 'react'
import '../css/Proudct.css'
import { useStateValue } from './StateProvider';
import { nanoid } from 'nanoid'
function Proudct({ title, currency, price, rate, image }) {
const [{ basket }, dispatch] = useStateValue();
const addToBasket = () => {
// dispatch the item into the data layer
dispatch({
type: "ADD_TO_BASKET",
item: {
title: title,
image: image,
price: price,
rate: rate,
},
});
};
return (
<div className='proudct'>
<p className='proudct--title'>{title}</p>
<div className='proudct--price'>
<small>{currency}</small>
<strong>{price}</strong>
</div>
<span className='proudct--rate'>{rate}</span>
<div className='proudct--image'>
<img src={image} />
</div>
<button onClick={addToBasket} className='proudct--button'>Add to Basket</button>
</div>
)
}
export default Proudct;

index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { createBrowserRouter, RouterProvider } from "react-router-dom"
import Checkout from './compenets/Checkout';
import Home from './compenets/Home';
import reducer, { initialState } from './compenets/Reducer';
import { StateProvider } from './compenets/StateProvider';
const routes = createBrowserRouter([
{
path: "/",
element: <App />,
children: [
{
index: true , element: <Home />
},
{
path: "checkout",
element: <Checkout />
}
]
}
])
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<RouterProvider router ={routes} /> 
<StateProvider initalState={initialState} reducer={reducer}>
</StateProvider>
</React.StrictMode>
)
reportWebVitals();

未处理的抛出错误!undefined不可迭代(无法读取属性Symbol(Symbol.iterator((TypeError:undefined不可迭代(无法读取属性Symbol(Symbol.iterator((在Proudct

当你的应用程序抛出错误时,你可以在<Route>上提供自己的errorElement道具,从而提供比这更好的用户体验

问题

您似乎没有为应用程序提供上下文值。

root.render(
<React.StrictMode>
<RouterProvider router={routes} /> 
<StateProvider initialState={initialState} reducer={reducer}>
</StateProvider>
</React.StrictMode>
);

没有默认的上下文值:

export const StateContext = createContext(); // <-- default value is undefined

当消费者试图破坏上下文值时,他们不能,因为他们接收的上下文值是未定义的。没有什么可以迭代和破坏的。

const [{ basket }, dispatch] = useStateValue(); // <-- can't iterate undefined

解决方案

提供默认上下文值是常见的,但不是必须的:

export const StateContext = createContext([
{ basket: [] }, // <-- object with expected properties and empty/default vlaues
() => {}        // <-- "dispatch" function
]);

上下文提供者仍然需要包装和呈现它为其提供值的ReactTree

StateProvider组件应该包装RouterProvider组件,以便在ReactTree中呈现的路由在其上方有一个上下文提供程序。

示例:

root.render(
<React.StrictMode>
<StateProvider initialState={initialState} reducer={reducer}>
<RouterProvider router={routes} /> 
</StateProvider>
</React.StrictMode>
);

相关内容

  • 没有找到相关文章

最新更新