我有点在学习react库的新功能/方法,而不是通过组件传递道具,而我使用钩子和contextapi来传递没有道具的数据。所以在某些情况下我会卡住 默认值,如果它在createContext中为空会给我该错误;它给我TypeError:无法读取未定义的属性'getWeather' 如果说像createContext(0)这样说value是0,它可以工作,但是没有获取数据。我错过了一些小问题,但不知道它在哪里:)?
我通过github repo共享该应用程序,任何人都可以检查出您是否有空并在我做错事情的地方帮我吗?
https://github.com/mrtyvz61/weather-finder-hooksContext
export const WeatherCtx = createContext();
const App = props => {
const [state, setState] = useState({
temprature: '',
city: '',
country: '',
humidity: '',
description: '',
error: ''
});
答案 0 :(得分:0)
使用上下文时,需要在提供程序内部呈现将使用它的所有组件。在您的代码中,您有以下内容:
<WeatherCtx.Provider
value={{
data: state,
getWeather
}}
>
{props.children}
</WeatherCtx.Provider>
...
下面是Weather
组件,它是使用上下文的组件。在这种情况下,Weather
(以及将要访问上下文值的所有组件)都必须位于提供程序内部:
<WeatherCtx.Provider ...>
...
// <-- Weather needs to be here
</WeatherCtx.Provider>
答案 1 :(得分:0)
我注意到的第一件事是您的API密钥在您的代码中。这不是什么大问题,因为它只是一个小项目,人们不太可能会滥用您的API密钥,但这是一个坏习惯。考虑使用环境变量存储API密钥而不是对其进行硬编码,这里是link for create-react-app,因为这是您正在使用的。
尝试仅传递state和getWeather而不是进行data: state, getWeather
。
一个有用的技巧是在表单组件中使用ReactDevTools甚至只是console.log(WeatherCtx)
来查看其值。
编辑:我只是注意到您的Context.Provider中没有包装您的组件
您需要像在Context.Provider中那样包装组件以尝试使用Context
<Context.Provider>
//Components that need to use context
</Context.Provider>
答案 2 :(得分:0)
Rect.CreateContext()
返回两个HOC
:Provider
和Consumer
。
提供商
定义上下文的位置。该组件带有一个称为value
的必需属性,它是您的上下文(通常是一个对象,但可以是任何东西)。假设我要通过上下文共享一个名为Planck
的常量。
第一步:定义上下文:
const Planck = 6.62607004
第二步:创建上下文:
const { Consumer, Provider } = React.CreateContext()
我们只是创建了上下文,但没有使用value
常量将其初始化为Planck
道具,因为这不是执行此操作的地方...
最后一步:设置
const TopLevelComponent = ({children}) =>{
return(
<Provider value={Planck}>
{children}
</Provider>
)
}
const Child = () =>{
return (
<Consumer>
{context => (
<div>{context /*PLANCK*/}</div>
)}
</Consumer>
)
}
现在我们用Planck
初始化了上下文,请注意,defaultValue
参数仅在CreateContext()
中使用,因为您知道该值不会改变,所以您不必不必全部使用Provider
。在这种情况下,我知道普朗克的常数不会改变(毕竟这是常数),所以我可以使用defaultValue
arg编写更少的代码:
const { Consumer } = React.CreateContext(Planck)
const Child = () =>{
return(
<Consumer>
{context => <div>{context/*Planck*/}</div>}
</Consumer>
)
}