You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将仅图片路径不同的两个React组件文件合并为一个?

React高重复组件合并复用方案

两个组件的UI结构、点击交互逻辑完全一致,唯一差异是列表项封面图的取值路径,只需将这个差异点抽为可配置的入参,即可用单个通用组件覆盖两个场景,彻底消除代码冗余。


核心思路

把会变的部分(图片取值规则)通过props传入组件,固定不变的结构和逻辑全部留在公共组件内部维护,后续如果要改样式、改交互逻辑,只需要改一次公共组件即可,不用同步修改多份代码。


方案1:高扩展性实现(推荐)

将图片地址的获取逻辑封装为函数作为props传入,后续新增同类列表(比如专辑、歌手列表)只要传入对应取值规则,不需要修改公共组件代码。

公共组件代码

const MediaList = props => {
    const handleClick = e => {
        props.onClick(e.target.title);
    }

    return (
        <section id={props.selectedValue} className="column column__hidden" onClick={handleClick}>
            <a className="link__decoration link__track hover__track link__one" href="#">
                <div>
                    {props.items.map((item, idx) => 
                    <div className="container" key={idx + 1} title={item.id} >
                        <div className="content__track" title={item.id}>
                            <img 
                                className="img__tarck" 
                                title={item.id} 
                                src={props.getImageSrc(item)}
                            />
                            <div className="name" title={item.id}>{item.name}</div>
                        </div>
                    </div>)}
                </div> 
            </a>
        </section>
    );
}

场景调用示例

  • 播放列表场景:
<MediaList
  selectedValue={/* 对应选中状态值 */}
  items={playlistItems}
  onClick={/* 对应点击回调函数 */}
  getImageSrc={item => item.images?.[0]?.url || ''}
/>
  • 流派分类场景:
<MediaList
  selectedValue={/* 对应选中状态值 */}
  items={genreItems}
  onClick={/* 对应点击回调函数 */}
  getImageSrc={item => item.icons?.[0]?.url || ''}
/>

方案2:轻量简化实现

如果后续不会新增其他同类列表场景,也可以直接加一个类型字段做内部判断,不用传函数,写法更简短:

const MediaList = props => {
    const handleClick = e => {
        props.onClick(e.target.title);
    }

    const getCoverSrc = item => {
        return props.listType === 'playlist' 
            ? item.images?.[0]?.url || '' 
            : item.icons?.[0]?.url || ''
    }

    return (
        <section id={props.selectedValue} className="column column__hidden" onClick={handleClick}>
            <a className="link__decoration link__track hover__track link__one" href="#">
                <div>
                    {props.items.map((item, idx) => 
                    <div className="container" key={idx + 1} title={item.id} >
                        <div className="content__track" title={item.id}>
                            <img 
                                className="img__tarck" 
                                title={item.id} 
                                src={getCoverSrc(item)}
                            />
                            <div className="name" title={item.id}>{item.name}</div>
                        </div>
                    </div>)}
                </div> 
            </a>
        </section>
    );
}

调用时传入类型即可:

  • 播放列表:<MediaList listType="playlist" {...其余props} />
  • 流派分类:<MediaList listType="genre" {...其余props} />

代码中新增了可选链?.和空值兜底,避免接口返回图片数组为空、字段缺失时触发JS报错,比原有直接读取[0].url的写法健壮性更高。

内容的提问来源于stack exchange,提问作者Сергей

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 00:01:04