通过自定义挂钩访问的自定义上下文提供程序中的值未定义



我正在学习React,在自定义上下文提供程序中定义的值遇到问题。我使用自定义钩子访问提供程序下的组件中的值,但报告为未定义。我已经复习了SO上的问题,并用书中的课程验证了我的语法,但找不到问题。

这是我的自定义提供者和自定义挂钩:

import React, { createContext, useState, useEffect, useContext } from 'react';
const ApiContext = createContext();
export const useApi = () => useContext(ApiContext);
export const ApiProvider = ({ children }) => {
const [loading, setLoading] = useState(false);
const [error, setError] = useState();
const [baseImageUrl, setBaseImageUrl] = useState();
const apiKey = 'api_key=SECRET';
const baseUrl = 'https://api.themoviedb.org/3';
const objToParams = (obj) => {
let params = '';
if(obj) {
const keys = Object.keys(obj);
for(let key of keys) {
params += `&${key}=${encodeURIComponent(obj[key])}`;
}
}
return params;
}
const api = {
get: async (path, params) => {
const resp = await fetch(baseUrl + path + '?' + apiKey + objToParams(params));
return await resp.json();
}
}
useEffect( () => {
try {
setLoading(true);
const config = api.get('/configuration');
console.log(config);
config.images && setBaseImageUrl(config.images.secure_base_url);
}
catch (error) {
console.error(error);
setError(error);
}
finally {
setLoading(false);
}
}, []);
if( loading ) {
return <p>Loading...</p>;
}
if( error ) {
return <pre>{JSON.stringify(error, null, 2)}</pre>;
}
return (
<ApiContext.Provider value={{ api, baseImageUrl }}>
{ children }
</ApiContext.Provider>
);
}

这是我通过自定义挂钩访问值的组件:

import React, { useState } from 'react';
import { ApiProvider, useApi } from './components/context/ApiProvider';
import Header from './components/Header';
import Main from './components/Main';
import Footer from './components/Footer';
import './App.css';
const App = () => {
const [searching, setSearching] = useState(false);
const [searchResults, setSearchResults] = useState([])
const [searchError, setSearchError] = useState();
const {api} = useApi();
const onSearch = (query) => {
try {
setSearching(true);
setSearchResults(api.get('/search/multi', {query: encodeURIComponent(query)} ));
console.log(searchResults);
}
catch (error) {
console.error(error);
setSearchError(error);
}
finally {
setSearching(false);
}
}
return (
<ApiProvider>
<div className="main-layout">
<Header onSearch={ onSearch }/>
<Main
searching={ searching }
searchError={ searchError }
searchResults={ searchResults }
/>
<Footer />
</div>
</ApiProvider>
);
}
export default App;

您不能在应用上下文的组件中使用上下文。

<ComponentA>
<Context.Provider value={"somethong"} >
<ComponentB/>
</Context.Provider>
</ComponentA>

在上面的示例中,只有ComponentB可以使用该值。组件A不能。如果您不想在应用程序组件中使用该值,那么它必须是ContextProvider的子级(或孙级…(。

<Context.Provider value={"somethong"} >
<App/>
</Context.Provider>

如果我正确理解了你的代码,那么你就试图在应用程序中使用上下文,同时返回相同上下文的提供者。

最新更新