我正在使用Next.js和React,使用反应钩子+上下文来管理状态。但是,我遇到了这个问题,即使我正在传递上下文对象(或者我认为无论如何,无论如何,React.useContext()
返回未定义的。我错过了一些非常明显的东西吗?发生了什么事情?
我在一个名为 CartContext 的 const 中创建上下文,然后在我的提供程序组件中,我创建了值对象并将其作为 prop 传递给 CartContext.Provider(见下文_app.js
(。我通过添加一个<h1>
元素来确保上下文提供程序包装我的组件,只是为了确保。
问题似乎发生在index.js
.我已经从./_app.js
导入了 CartContext,然后将其作为参数传递给useContext()
这应该是我应该做的,但它不断抛出此错误:
"TypeError: 无法解构'react__WEBPACK_IMPORTED_MODULE_0___default.a.useContext(...('的属性'firstSample',因为它未定义">
从我收集的内容告诉我,useContext(( 返回的是未定义的。
_app.js(换行所有页面(
import React from 'react'
import '../styles/global.css';
import theme from '../components/customTheme';
import { ThemeProvider } from '@material-ui/core/styles';
const MyApp = props => {
const { Component, pageProps, store } = props
return (
<ContextProvider>
<ThemeProvider theme={theme}>
<Component {...pageProps} />
</ThemeProvider>
</ContextProvider>
)
}
// Context
export const CartContext = React.createContext()
function ContextProvider({ children }) {
const value = {
firstSample: "Test",
exampleFunction: () => {alert("Hello World")},
}
return (
<CartContext.Provider value={value}>
<h1>The provider works</h1>
{children}
</CartContext.Provider>
)
}
export default MyApp;
索引.js
import Nav from '../components/nav';
import Footer from '../components/footer';
import Product from '../components/product';
import { makeStyles } from '@material-ui/core/styles';
import CartContext from './_app';
import {
Typography,
Button
} from '@material-ui/core';
const useStyles = makeStyles({
body: {
margin: '13vh 0 3vh',
backgroundColor: ' white',
textAlign: 'left'
},
earnWrapper: {
display: 'block',
textAlign: 'left',
backgroundColor: 'white',
width: 'calc(100% - 4vh)',
margin: '5% 2vh 12%',
borderRadius: '25px',
transition: '0.3s',
boxShadow: '0px 5px 20px #dedede'
},
earnContent: {
padding: '7%',
textAlign: 'left',
display: 'inline-block'
},
earntCaption: {
color: 'grey',
},
earntAmount: {
margin: '0.5vh 0 1.5vh'
},
withdraw: {
width: '130px',
height: '40px'
},
shareInfo: {
margin: '5% 2vh',
textAlign: 'left'
},
products: {
textAlign: 'center ',
width: '100%'
}
});
export default function Home(props) {
const styles = useStyles();
// Grab data from parent context
const { firstSample } = React.useContext(
CartContext
)
return (
<div>
<DefaultHead
title="Oorigin | Home"
/>
<Nav isLoggedIn={true} />
<div className={styles.body}>
<div className={styles.earnWrapper}>
<div className={styles.earnContent}>
<Typography className={styles.earntCaption} variant="caption">You've earned</Typography>
<Typography className={styles.earntAmount} variant="h4">S$18.50</Typography>
<Button className={styles.withdraw} disableElevation variant="contained" color="primary">Withdraw</Button>
</div>
</div>
<div className={styles.shareInfo}>
<Typography><b>Shop, Share, Earn</b></Typography>
<Typography><br/>Shop products you like, share products you love, and earn up to 10% commission on every qualifying sale you refer</Typography>
</div>
<div className={styles.products}>
<Product
imgURL="../TestItem1.svg"
imgAlt="Test Product"
title="Disinfecting Air Purifying Solution"
price={(22.80).toFixed(2)}
link="/products/staticProduct"
/>
<Product
imgURL="../TestItem2.svg"
imgAlt="Test Product"
title="Disinfecting Air Purifying Solution"
price={(22.80).toFixed(2)}
/>
<Product
imgURL="../TestItem3.svg"
imgAlt="Test Product"
title="Disinfecting Air Purifying Solution"
price={(22.80).toFixed(2)}
/>
<Product
imgURL="../TestItem4.svg"
imgAlt="Test Product"
title="Disinfecting Air Purifying Solution"
price={(22.80).toFixed(2)}
/>
</div>
</div>
<Footer/>
<h1>{firstSample}</h1>
</div>
);
}
好的,这是一个非常简单的错误,我在index.js
中导入了CartContext
import cartContex from _app.js
,当它应该带有大括号时,因为它不是默认导出。所以更正的(功能(代码很简单:import { cartContext } from _app.js
尝试像这样导入:
import { CartContext } from './_app';
您的代码存在一些问题,我不明白为什么您的createContext
留在组件<MyApp />
上。
问题:
- 在你正在做的
MyApp
组件中export default MyApp
和export CartContext
,我相信这是不可能的。 - 你的
createContext
没有defaultValue
,也许这就是返回undefined
的原因。请参阅文档中的示例
我相信通过进行这些更改,您的代码应该可以工作,或者至少您可以随着问题的发展而发展。
使用代码沙箱会更容易。