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/components/VideoOverlay.tsx b/client/src/components/VideoOverlay.tsx
index 93106ab..11dead5 100644
--- a/client/src/components/VideoOverlay.tsx
+++ b/client/src/components/VideoOverlay.tsx
@@ -16,12 +16,12 @@
* <https://www.gnu.org/licenses/>.
*/
import { Box } from '@mui/material';
-import { useContext, useRef, useState } from 'react';
+import { useRef, useState } from 'react';
import Draggable, { DraggableEventHandler } from 'react-draggable';
import { useNavigate } from 'react-router-dom';
-import { CallContext } from '../contexts/CallProvider';
-import { WebRtcContext } from '../contexts/WebRtcProvider';
+import { useCallContext } from '../contexts/CallProvider';
+import { useWebRtcContext } from '../contexts/WebRtcProvider';
import { VideoElementWithSinkId } from '../utils/utils';
import VideoStream, { VideoStreamProps } from './VideoStream';
@@ -75,12 +75,12 @@
};
export const RemoteVideoOverlay = ({ callConversationId }: { callConversationId: string }) => {
- const { remoteStreams } = useContext(WebRtcContext);
+ const { remoteStreams } = useWebRtcContext();
const {
currentMediaDeviceIds: {
audiooutput: { id: audioOutDeviceId },
},
- } = useContext(CallContext);
+ } = useCallContext();
const navigate = useNavigate();
// TODO: For now, `remoteStream` is the first remote stream in the array.