如果只有一个状态更新,React 组件不会重新渲染



我有 2 个组件 -> a( VideoJSPlayer 和 b(视频页面。

顾名思义,VideoJsPlayer具有视频播放器部分(使用videojs(,VideosPage使用VideoJsPlayer组件显示视频。

每个组件的代码为:

a( VideoJsPlayer

import React, { useEffect } from "react";
import videojs from "video.js";
const VideoJsPlayer = props => {
let player = null;
let videoNode = null;
// Effect for first render only.
useEffect(() => {
player = videojs(videoNode, props, function onPlayerReady() {
console.log("onPlayerReady");
});
return function cleanup() {
if (player) {
player.dispose();
}
};
}, []);
return (
<div>
<div data-vjs-player>
<video ref={node => (videoNode = node)} className="video-js"></video>
</div>
</div>
);
};
export default VideoJsPlayer;

b( 视频页面

import React, { useState, useEffect } from "react";
import videojs from "video.js";
import VideoJsPlayer from "../../components/VideoJsPlayer";
const VideosPage = props => {
const [videoJsOptions, setVideoJsOptions] = useState({});
// Effect for first render only.
useEffect(() => {
let videoJsOptionsTest = {
autoplay: false,
controls: true,
sources: [
{
src: "/my-video.mp4",
type: "video/mp4"
}
]
};
console.log("test");
setVideoJsOptions(videoJsOptionsTest);
// Cleanup on unmount.
return function cleanup() {};
}, []);
return (
<React.Fragment>
<VideoJsPlayer {...videoJsOptions} />
</React.Fragment>
);
};
export default VideosPage;

当我检查呈现视频页面组件的 URL 时,我没有看到任何视频。我假设状态(videoJsOptions(尚未在视频页面中更新,因此我看不到视频。我可以看到控制台日志 - "测试"。

当我将视频页面的代码更改为:

import React, { useState, useEffect } from "react";
import videojs from "video.js";
import VideoJsPlayer from "../../components/VideoJsPlayer";
const VideosPage = props => {
const [videoJsOptions, setVideoJsOptions] = useState({
autoplay: false,
controls: true,
sources: [
{
src: "/my-video.mp4",
type: "video/mp4"
}
]
});
// Effect for first render only.
useEffect(() => {
/*
let videoJsOptionsTest = {
autoplay: false,
controls: true,
sources: [
{
src: "/my-video.mp4",
type: "video/mp4"
}
]
};
console.log("test");
setVideoJsOptions(videoJsOptionsTest);
*/
// Cleanup on unmount.
return function cleanup() {};
}, []);
return (
<React.Fragment>
<VideoJsPlayer {...videoJsOptions} />
</React.Fragment>
);
};
export default VideosPage;

现在,当我检查呈现视频页面组件的URL时,我看到了视频。

我的假设是 - 在第一种情况下,状态更新是排队的,永远不会发生。因为如果它确实发生了,它应该重新渲染组件,我应该看过我的视频。

我也尝试在VideoJSPlayer中更新useEffect,以便在每次道具更改时运行,但没有帮助。

对此有什么见解吗?

谢谢你的时间。

这是一个沙盒:代码沙盒

你有一些错误:

  1. 你不能使用这样的videoNode,因为 Video.js 使用Ref并且由于你使用的是 React 钩子,你需要使用 useRef
import React, { useRef, useEffect } from "react"
const VideoJsPlayer = props => {
const videoRef = useRef(null)
useEffect(() => {
//...
videojs(
videoRef.current,
props,
function onPlayerReady() {
console.log("onPlayerReady")
}
)
//...
}, [])
return (
<video ref={videoRef} className="video-js" />
)
}
  1. 您无需在VideosPage组件中再次使用useEffect,因为它已经在VideoJsPlayer组件中使用。您的初始选项需要直接在state或函数外部设置,如下所示:
const initialOptions = {
// ...
}
const VideosPage = () => {
return <VideoJsPlayer {...initialOptions} />
}

下面是一个基于您的代码的工作 codeSandbox 示例。

相关内容

  • 没有找到相关文章

最新更新