Prefer React.memo to useMemo when memoizing components
This commit is contained in:
parent
155e41136c
commit
e486aab770
|
@ -6,7 +6,7 @@ import {
|
||||||
GetAudioProgress,
|
GetAudioProgress,
|
||||||
} from './generated/media_set';
|
} from './generated/media_set';
|
||||||
|
|
||||||
import { useState, useEffect, useRef, useMemo } from 'react';
|
import { useState, useEffect, useRef, useCallback } from 'react';
|
||||||
import { VideoPreview } from './VideoPreview';
|
import { VideoPreview } from './VideoPreview';
|
||||||
import { Overview, CanvasLogicalWidth } from './Overview';
|
import { Overview, CanvasLogicalWidth } from './Overview';
|
||||||
import { Waveform } from './Waveform';
|
import { Waveform } from './Waveform';
|
||||||
|
@ -178,6 +178,16 @@ function App(): JSX.Element {
|
||||||
video.currentTime = currentTime;
|
video.currentTime = currentTime;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handlePlay = useCallback(() => {
|
||||||
|
audio.play();
|
||||||
|
video.play();
|
||||||
|
}, [audio, video]);
|
||||||
|
|
||||||
|
const handlePause = useCallback(() => {
|
||||||
|
video.pause();
|
||||||
|
audio.pause();
|
||||||
|
}, [audio, video]);
|
||||||
|
|
||||||
// render component
|
// render component
|
||||||
|
|
||||||
const containerStyles = {
|
const containerStyles = {
|
||||||
|
@ -192,24 +202,6 @@ function App(): JSX.Element {
|
||||||
|
|
||||||
const offsetPixels = Math.floor(thumbnailWidth / 2);
|
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) {
|
if (mediaSet == null) {
|
||||||
// TODO: improve
|
// TODO: improve
|
||||||
return <></>;
|
return <></>;
|
||||||
|
@ -219,7 +211,8 @@ function App(): JSX.Element {
|
||||||
<>
|
<>
|
||||||
<div className="App">
|
<div className="App">
|
||||||
<div style={containerStyles}>
|
<div style={containerStyles}>
|
||||||
{controlBar}
|
<ControlBar onPlay={handlePlay} onPause={handlePause} />
|
||||||
|
|
||||||
<Overview
|
<Overview
|
||||||
peaks={overviewPeaks}
|
peaks={overviewPeaks}
|
||||||
mediaSet={mediaSet}
|
mediaSet={mediaSet}
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
onPlay: () => void;
|
onPlay: () => void;
|
||||||
onPause: () => 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 styles = { width: '100%', flexGrow: 0 };
|
||||||
const buttonStyles = {
|
const buttonStyles = {
|
||||||
cursor: 'pointer',
|
cursor: 'pointer',
|
||||||
|
@ -27,4 +29,7 @@ export const ControlBar: React.FC<Props> = (props: Props) => {
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
});
|
||||||
|
|
||||||
|
ControlBar.displayName = 'ControlBar';
|
||||||
|
export { ControlBar };
|
||||||
|
|
|
@ -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 { MediaSet } from './generated/media_set';
|
||||||
import { Frames, VideoPosition } from './App';
|
import { Frames, VideoPosition } from './App';
|
||||||
import { WaveformCanvas } from './WaveformCanvas';
|
import { WaveformCanvas } from './WaveformCanvas';
|
||||||
|
@ -336,21 +336,16 @@ export const Overview: React.FC<Props> = ({
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div style={containerStyles}>
|
<div style={containerStyles}>
|
||||||
{useMemo(
|
<WaveformCanvas
|
||||||
() => (
|
peaks={peaks}
|
||||||
<WaveformCanvas
|
channels={mediaSet.audioChannels}
|
||||||
peaks={peaks}
|
width={CanvasLogicalWidth}
|
||||||
channels={mediaSet.audioChannels}
|
height={CanvasLogicalHeight}
|
||||||
width={CanvasLogicalWidth}
|
strokeStyle="black"
|
||||||
height={CanvasLogicalHeight}
|
fillStyle="#003300"
|
||||||
strokeStyle="black"
|
zIndex={1}
|
||||||
fillStyle="#003300"
|
alpha={1}
|
||||||
zIndex={1}
|
></WaveformCanvas>
|
||||||
alpha={1}
|
|
||||||
></WaveformCanvas>
|
|
||||||
),
|
|
||||||
[peaks, mediaSet]
|
|
||||||
)}
|
|
||||||
<canvas
|
<canvas
|
||||||
ref={hudCanvasRef}
|
ref={hudCanvasRef}
|
||||||
width={CanvasLogicalWidth}
|
width={CanvasLogicalWidth}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { useEffect, useState, useRef, useMemo } from 'react';
|
import { useEffect, useState, useRef } from 'react';
|
||||||
import { Frames, VideoPosition, newRPC } from './App';
|
import { Frames, VideoPosition, newRPC } from './App';
|
||||||
import { MediaSetServiceClientImpl, MediaSet } from './generated/media_set';
|
import { MediaSetServiceClientImpl, MediaSet } from './generated/media_set';
|
||||||
import { WaveformCanvas } from './WaveformCanvas';
|
import { WaveformCanvas } from './WaveformCanvas';
|
||||||
|
@ -112,21 +112,16 @@ export const Waveform: React.FC<Props> = ({
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div style={containerStyles}>
|
<div style={containerStyles}>
|
||||||
{useMemo(
|
<WaveformCanvas
|
||||||
() => (
|
peaks={peaks}
|
||||||
<WaveformCanvas
|
channels={mediaSet.audioChannels}
|
||||||
peaks={peaks}
|
width={CanvasLogicalWidth}
|
||||||
channels={mediaSet.audioChannels}
|
height={CanvasLogicalHeight}
|
||||||
width={CanvasLogicalWidth}
|
strokeStyle="green"
|
||||||
height={CanvasLogicalHeight}
|
fillStyle="black"
|
||||||
strokeStyle="green"
|
zIndex={0}
|
||||||
fillStyle="black"
|
alpha={1}
|
||||||
zIndex={0}
|
></WaveformCanvas>
|
||||||
alpha={1}
|
|
||||||
></WaveformCanvas>
|
|
||||||
),
|
|
||||||
[peaks, mediaSet]
|
|
||||||
)}
|
|
||||||
<canvas
|
<canvas
|
||||||
width={CanvasLogicalWidth}
|
width={CanvasLogicalWidth}
|
||||||
height={CanvasLogicalHeight}
|
height={CanvasLogicalHeight}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { useEffect, useRef } from 'react';
|
import React, { useEffect, useRef } from 'react';
|
||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
|
|
||||||
const maxPeakValue = 32_768;
|
const maxPeakValue = 32_768;
|
||||||
|
@ -22,7 +22,7 @@ interface Props {
|
||||||
// strokeStyle: waveform style
|
// strokeStyle: waveform style
|
||||||
// fillStyle: background style
|
// fillStyle: background style
|
||||||
// style: React.CSSProperties applied to canvas element
|
// 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);
|
const canvasRef = useRef<HTMLCanvasElement>(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -89,4 +89,7 @@ export const WaveformCanvas: React.FC<Props> = (props: Props) => {
|
||||||
></canvas>
|
></canvas>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
});
|
||||||
|
|
||||||
|
WaveformCanvas.displayName = 'WaveformCanvas';
|
||||||
|
export { WaveformCanvas };
|
||||||
|
|
Loading…
Reference in New Issue