Prefer React.memo to useMemo when memoizing components

This commit is contained in:
Rob Watson 2021-12-04 05:34:17 +01:00
parent 155e41136c
commit e486aab770
5 changed files with 48 additions and 57 deletions

View File

@ -6,7 +6,7 @@ import {
GetAudioProgress,
} from './generated/media_set';
import { useState, useEffect, useRef, useMemo } from 'react';
import { useState, useEffect, useRef, useCallback } from 'react';
import { VideoPreview } from './VideoPreview';
import { Overview, CanvasLogicalWidth } from './Overview';
import { Waveform } from './Waveform';
@ -178,6 +178,16 @@ function App(): JSX.Element {
video.currentTime = currentTime;
};
const handlePlay = useCallback(() => {
audio.play();
video.play();
}, [audio, video]);
const handlePause = useCallback(() => {
video.pause();
audio.pause();
}, [audio, video]);
// render component
const containerStyles = {
@ -192,24 +202,6 @@ function App(): JSX.Element {
const offsetPixels = Math.floor(thumbnailWidth / 2);
// Avoid re-rendering this component during playback. Needs to be memoized
// before the mediaSet null check below.
const controlBar = useMemo(
() => (
<ControlBar
onPlay={() => {
audio.play();
video.play();
}}
onPause={() => {
video.pause();
audio.pause();
}}
/>
),
[]
);
if (mediaSet == null) {
// TODO: improve
return <></>;
@ -219,7 +211,8 @@ function App(): JSX.Element {
<>
<div className="App">
<div style={containerStyles}>
{controlBar}
<ControlBar onPlay={handlePlay} onPause={handlePause} />
<Overview
peaks={overviewPeaks}
mediaSet={mediaSet}

View File

@ -1,9 +1,11 @@
import React from 'react';
interface Props {
onPlay: () => void;
onPause: () => void;
}
export const ControlBar: React.FC<Props> = (props: Props) => {
const ControlBar: React.FC<Props> = React.memo((props: Props) => {
const styles = { width: '100%', flexGrow: 0 };
const buttonStyles = {
cursor: 'pointer',
@ -27,4 +29,7 @@ export const ControlBar: React.FC<Props> = (props: Props) => {
</div>
</>
);
};
});
ControlBar.displayName = 'ControlBar';
export { ControlBar };

View File

@ -1,4 +1,4 @@
import { useState, useEffect, useRef, useMemo, MouseEvent } from 'react';
import { useState, useEffect, useRef, MouseEvent } from 'react';
import { MediaSet } from './generated/media_set';
import { Frames, VideoPosition } from './App';
import { WaveformCanvas } from './WaveformCanvas';
@ -336,21 +336,16 @@ export const Overview: React.FC<Props> = ({
return (
<>
<div style={containerStyles}>
{useMemo(
() => (
<WaveformCanvas
peaks={peaks}
channels={mediaSet.audioChannels}
width={CanvasLogicalWidth}
height={CanvasLogicalHeight}
strokeStyle="black"
fillStyle="#003300"
zIndex={1}
alpha={1}
></WaveformCanvas>
),
[peaks, mediaSet]
)}
<WaveformCanvas
peaks={peaks}
channels={mediaSet.audioChannels}
width={CanvasLogicalWidth}
height={CanvasLogicalHeight}
strokeStyle="black"
fillStyle="#003300"
zIndex={1}
alpha={1}
></WaveformCanvas>
<canvas
ref={hudCanvasRef}
width={CanvasLogicalWidth}

View File

@ -1,4 +1,4 @@
import { useEffect, useState, useRef, useMemo } from 'react';
import { useEffect, useState, useRef } from 'react';
import { Frames, VideoPosition, newRPC } from './App';
import { MediaSetServiceClientImpl, MediaSet } from './generated/media_set';
import { WaveformCanvas } from './WaveformCanvas';
@ -112,21 +112,16 @@ export const Waveform: React.FC<Props> = ({
return (
<>
<div style={containerStyles}>
{useMemo(
() => (
<WaveformCanvas
peaks={peaks}
channels={mediaSet.audioChannels}
width={CanvasLogicalWidth}
height={CanvasLogicalHeight}
strokeStyle="green"
fillStyle="black"
zIndex={0}
alpha={1}
></WaveformCanvas>
),
[peaks, mediaSet]
)}
<WaveformCanvas
peaks={peaks}
channels={mediaSet.audioChannels}
width={CanvasLogicalWidth}
height={CanvasLogicalHeight}
strokeStyle="green"
fillStyle="black"
zIndex={0}
alpha={1}
></WaveformCanvas>
<canvas
width={CanvasLogicalWidth}
height={CanvasLogicalHeight}

View File

@ -1,4 +1,4 @@
import { useEffect, useRef } from 'react';
import React, { useEffect, useRef } from 'react';
import { Observable } from 'rxjs';
const maxPeakValue = 32_768;
@ -22,7 +22,7 @@ interface Props {
// strokeStyle: waveform style
// fillStyle: background style
// style: React.CSSProperties applied to canvas element
export const WaveformCanvas: React.FC<Props> = (props: Props) => {
const WaveformCanvas: React.FC<Props> = React.memo((props: Props) => {
const canvasRef = useRef<HTMLCanvasElement>(null);
useEffect(() => {
@ -89,4 +89,7 @@ export const WaveformCanvas: React.FC<Props> = (props: Props) => {
></canvas>
</>
);
};
});
WaveformCanvas.displayName = 'WaveformCanvas';
export { WaveformCanvas };