[英]Typescript class as React state, rerender
我有以下 function 組件:
const Player = () => {
const [spotifyPlayer, setSpotifyPlayer] = React.useState<SpotifyPlayer | null>(null);
return (
<SongControls togglePlay={togglePlay} isPlaying={spotifyPlayer.isPlaying} />
);
};
SongControls
組件負責顯示正確的控制按鈕(開始/暫停):
const SongControls: React.FC<Props> = ({ isPlaying }: Props) => {
return (
{isPlaying ? (
<Pause style={iconBig} onClick={togglePlay} />
) : (
<PlayArrow style={iconBig} onClick={togglePlay} />
)}
);
};
Player
組件中的spotifyPlayer
state 是一個 class ,其字段isPlaying
的類型為boolean
。 它還有一個 function 定義的togglePlay()
來切換isPlaying
。
問題是,當togglePlay()
時,React 不會重新渲染組件。 我明白為什么(因為 SpotifyPlayer 的實例沒有改變,這就是為什么你不應該直接更新 react state)。
由於兩個原因,我無法調用setSpotifyPlayer()
來更新 state:
SpotifyPlayer
的實例負責切換isPlaying
spotifyPlayer
state 的原型,並且 function 將不再可用。我無法弄清楚這一點。
你對問題的理解是正確的。 您不能依賴SpotifyPlayer
object 的內部 state 的更改來觸發重新渲染。 我建議使用本地 state 來存儲isPlaying
的值並根據對該值的更改更新SpotifyPlayer
。
如果播放器 object 有某種onChange
監聽器,那么我將使用播放器設置本地 state 而不是相反。
我不確定播放器來自什么 package,所以我假設這個界面:
class SpotifyPlayer {
isPlaying: boolean = false;
play(): void {
this.isPlaying = true;
}
pause(): void {
this.isPlaying = false;
}
}
我們可以使用useRef
來存儲對播放器 object 的一致引用。
const spotifyPlayer = React.useRef<SpotifyPlayer>(new SpotifyPlayer()).current;
我們將isPlaying
的值存儲在本地 state 中。 我們可以從玩家那里得到初始值。
const [isPlaying, setIsPlaying] = React.useState(spotifyPlayer.isPlaying);
為了使isPlaying
與播放器保持同步,我們可以使用useEffect
。
const togglePlay = () => setIsPlaying(!isPlaying);
React.useEffect(() => {
if ( isPlaying && ! spotifyPlayer.isPlaying ) {
spotifyPlayer.play();
} else if ( ! isPlaying && spotifyPlayer.isPlaying ) {
spotifyPlayer.pause();
}
}, [spotifyPlayer, isPlaying]);
但是如果togglePlay
是唯一會改變值的 function,那么我們可以處理 function 中的變化。
const togglePlay = () => {
if (isPlaying ) {
spotifyPlayer.pause();
setIsPlaying(false);
} else {
spotifyPlayer.play();
setIsPlaying(true);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.