[英]How to create a class service provider that consumes an external context in React?
I'm trying to create a service class that provides the whole application with common access to an e xternal Rest api.我正在尝试创建一个服务类,为整个应用程序提供对外部 Rest api 的公共访问。
The first issue I face is that this external api needs to be consumed as a Context, so my first approach was to create a custom context to consume and configure all the rest calls.我面临的第一个问题是这个外部 api 需要作为 Context 使用,所以我的第一种方法是创建一个自定义上下文来使用和配置所有其余的调用。 See code:
见代码:
export const ApiContext = createContext();
const ApiProvider = ({ children }) => {
const api = externalApiContext();
const get = (url, params) =>
api.get(urlWithParams(`${baseUrl}${url}${admkey}`, params));
const post = (url, body, params = {}, headers = {}) =>
api.post(urlWithParams(`${baseUrl}${url}${admkey}`, params), {
headers: { ...headers, 'Content-Type': 'application/json' },
body: JSON.stringify(body),
});
const put = (url, body, params = {}, headers = {}) =>
api.put(urlWithParams(`${baseUrl}${url}${admkey}`, params), {
headers: { ...headers, 'Content-Type': 'application/json' },
body: JSON.stringify(body),
});
const remove = (url, params = {}, headers = {}) =>
api.remove(urlWithParams(`${baseUrl}${url}${admkey}`, params), {
headers: { ...headers, 'Content-Type': 'application/json' },
});
const fetch = (url) => api.get(`${url}`);
return (
<ApiContext.Provider value={{ get, post, put, remove, fetch }}>
{children}
</ApiContext.Provider>
);
};
This works fine.这工作正常。 I can configure and make the calls all around the application.
我可以在应用程序周围配置和进行调用。 The problem is: Whenever I make any of these calls, all of them are re-rendered as my context seems to have changed .
问题是:每当我进行这些调用中的任何一个时,所有这些调用都会重新呈现,因为我的上下文似乎已经改变了。
So I have 2 doubts:所以我有两个疑问:
By the other hand, I was trying to create a service class like posted here: https://newbedev.com/having-services-in-react-application .另一方面,我试图创建一个像这里发布的服务类: https : //newbedev.com/have-services-in-react-application 。 But then, inside a service class, a Context cannot be used... So...
但是,在服务类中,不能使用 Context ......所以......
Thanks in advance!提前致谢!
As a start, you need to realize why your components re-render:首先,您需要了解为什么您的组件要重新渲染:
ApiProvider
re-renders because, either it's parent component re-renders or because children
changed. ApiProvider
重新渲染,因为它的父组件重新渲染或因为children
组件发生了变化。 children
is the most obvious candidate here. children
是这里最明显的候选人。
The problem then is that every time ApiProvider
renders, you provide a completely new context value:那么问题在于,每次
ApiProvider
呈现时,您都会提供一个全新的上下文值:
<ApiContext.Provider value={{ get, post, put, remove, fetch }}>
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
\ new object everytime!
Which forces every consumer of that context value to re-render as well.这迫使该上下文值的每个消费者也重新渲染。 The simplest solution would be to wrap everything with
useCallback
and the context value itself with useMemo
.最简单的解决办法是用包裹一切
useCallback
与上下文值本身useMemo
。
Something like:就像是:
export const ApiContext = createContext();
const ApiProvider = ({ children }) => {
const api = externalApiContext();
const get = useCallback(
(url, params) => api.get(urlWithParams(`${baseUrl}${url}${admkey}`, params)),
[api]
);
// ...repeat for a others...
return (
<ApiContext.Provider value={useMemo(
() => ({ get, post, put, remove, fetch }),
[get, post, put, remove, fetch]
)} children={children}/>
);
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.