React props在ES6类组件中的传值问题及组件选型咨询
问题描述
我正在参加编程训练营,需要在两天内学习React并完成类YouTube项目,当前用Babel编译代码。尝试把App组件中的exampleVideoData2通过props传递给VideoList组件展示视频数据,但传递失败,怀疑是this指向错误或props使用不当。目前代码已经写了不少,纠结要不要重构为函数组件。
相关代码如下:
App.js
import VideoPlayer from "/compiled/src/components/VideoPlayer.js"; import exampleVideoData2 from "../data/exampleVideoData2.js"; import VideoList from "/compiled/src/components/VideoList.js"; import Search from "/compiled/src/components/Search.js" class App extends React.Component{ constructor(props){ super() this.videos = exampleVideoData2 } render() { return( <div> <nav className="navbar"> <div className="col-md-6 offset-md-3"> <div><h5><em>search</em> view goes here</h5></div> </div> </nav> <div className="row"> <div className="col-md-7"> <div><h5><VideoPlayer /></h5></div> </div> <div className="col-md-5"> <div><h5><VideoList videos= { this.props.videos }/></h5></div> </div> </div> </div> )}; } export default App;
VideoList.js
import exampleVideoData2 from "/compiled/src/data/exampleVideoData.js"; import VideoListEntry from "/compiled/src/components/VideoListEntry.js" class VideoList extends React.Component{ constructor(props){ super(props); this.videos = exampleVideoData2 } videos(){ return(exampleVideoData2) } render(){ return ( <div className="video-list"> <div><h5> videos: { this.props.videos }</h5></div> <div><h5><em>videoListEntry</em> view goes here</h5></div> <div><h5><em>videoListEntry</em> view goes here</h5></div> <div><h5><em>videoListEntry</em> view goes here</h5></div> <div><h5><em>videoListEntry</em> view goes here</h5></div> </div> )}; }; VideoList.propTypes = { videos: PropTypes.array.isRequired, }; export default VideoList;
解决方案
1. 修复Props传递问题
你的代码里有两个关键错误导致props传递失败:
- App组件传递错误:你在constructor里把
exampleVideoData2赋值给了实例属性this.videos,但传递给VideoList时误用了this.props.videos——this.props是App组件自身接收的外部props,并非你定义的内部数据,应该改成传递this.videos。 - VideoList冗余代码:你在VideoList里重复导入数据并赋值给
this.videos,完全没必要。组件应该直接使用父组件传递来的this.props.videos,不需要硬编码本地数据。
修改后的代码:
修正后的App.js
import VideoPlayer from "/compiled/src/components/VideoPlayer.js"; import exampleVideoData2 from "../data/exampleVideoData2.js"; import VideoList from "/compiled/src/components/VideoList.js"; import Search from "/compiled/src/components/Search.js" class App extends React.Component{ constructor(props){ super(props); // 规范写法:将props传给super this.videos = exampleVideoData2; } render() { return( <div> <nav className="navbar"> <div className="col-md-6 offset-md-3"> <div><h5><em>search</em> view goes here</h5></div> </div> </nav> <div className="row"> <div className="col-md-7"> <div><h5><VideoPlayer /></h5></div> </div> <div className="col-md-5"> {/* 修正为传递实例属性this.videos */} <div><h5><VideoList videos={this.videos}/></h5></div> </div> </div> </div> ); } } export default App;
修正后的VideoList.js
import VideoListEntry from "/compiled/src/components/VideoListEntry.js" class VideoList extends React.Component{ constructor(props){ super(props); // 删除冗余的数据导入和实例属性赋值 } render(){ return ( <div className="video-list"> {/* 用JSON.stringify方便查看数据是否传递成功 */} <div><h5> videos: {JSON.stringify(this.props.videos)}</h5></div> {/* 循环渲染VideoListEntry,替代硬写的占位符 */} {this.props.videos.map(video => ( <VideoListEntry key={video.id} video={video} /> ))} </div> ); } }; VideoList.propTypes = { videos: PropTypes.array.isRequired, }; export default VideoList;
2. 是否需要重构为函数组件?
如果你的项目目前只是静态数据展示、没有复杂的生命周期逻辑,重构为函数组件+Hooks会更简洁,代码量更少。但考虑到你只剩两天时间,且现有类组件代码已经推进较多,优先修复当前props问题完成功能更高效。
等项目完成后,如果有时间可以尝试重构——函数组件是当前React的主流写法,学习成本不高,用useState、useEffect就能替代类组件的大部分功能。但当前阶段,先保证功能跑起来是核心目标。
内容的提问来源于stack exchange,提问作者barrington hebert
相关产品推荐
相关产品推荐

