Fix components rerendering unnecessarily
Before, some providers (WebRtcProvider, CallProvider...) were rendered conditionally.
This was causing all their children to re-render when the provider rendered.
Instead of using conditional rendering, these providers now use `ConditionalContextProvider`.
It always renders the provider, but sets its value to `initialValue` if the dependencies are not all defined.
If all dependencies are defined, the value is the result of the `useProviderValue` hook.
Changes:
- New file: `ConditionalContextProvider`
- New file: `HookComponent` - Component that calls a hook when mounted and calls a `callback` function with the hook result as argument
- For `WebRtcProvider` and `CallProvider`, use `createOptionalContext` to create the context and `ConditionalContextProvider` to provide their value only when the conditions are met
- In `WebRtcProvider`, set the webRtcConnection to undefined when not in a call
- For all providers, wrap their `value` prop in `useMemo` to avoid unnecessary rerenders
Change-Id: Ide947e216d54599aabc71cf4bd026bd20d6e0daf
diff --git a/client/src/contexts/AuthProvider.tsx b/client/src/contexts/AuthProvider.tsx
index 94f3dcf..8221745 100644
--- a/client/src/contexts/AuthProvider.tsx
+++ b/client/src/contexts/AuthProvider.tsx
@@ -94,21 +94,23 @@
axiosInstance.get<IAccount>('/account').then(({ data }) => setAccount(Account.fromInterface(data)));
}, [axiosInstance, logout]);
- if (!token || !account || !axiosInstance) {
+ const value = useMemo(() => {
+ if (!token || !account || !axiosInstance) {
+ return;
+ }
+
+ return {
+ token,
+ logout,
+ account,
+ accountId: account.id,
+ axiosInstance,
+ };
+ }, [token, logout, account, axiosInstance]);
+
+ if (!value) {
return <ProcessingRequest open />;
}
- return (
- <AuthContext.Provider
- value={{
- token,
- logout,
- account,
- accountId: account.id,
- axiosInstance,
- }}
- >
- {children}
- </AuthContext.Provider>
- );
+ return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
};