React开发中如何分组props和propTypes以减少冗余代码
你说的把公共props和propTypes抽离到外部文件是完全合理的解决方案,而且针对你当前的场景,还可以做更彻底的代码复用,完全不用为每个联赛单独写重复的组件文件。
方案1:用工厂函数批量生成联赛组件(最推荐)
你所有联赛组件的逻辑结构完全一致,仅competitionName/leagueName/flagUrl/alt这几个静态常量不同,完全可以封装一个组件生成函数,把差异化的内容当参数传入,直接生成对应联赛的组件:
// 首先抽离公共的propTypes到单独文件,比如 src/constants/leaguePropTypes.js import PropTypes from 'prop-types' export const leagueCommonPropTypes = { highlights: PropTypes.array, areHighlightsLoading: PropTypes.bool, haveHighlightsError: PropTypes.bool, standings: PropTypes.array, areStandingsLoading: PropTypes.bool, haveStandingsError: PropTypes.bool, scorers: PropTypes.array, areScorersLoading: PropTypes.bool, haveScorersError: PropTypes.bool, } // 再写组件工厂函数 src/utils/createLeagueComponent.js import League from './components/League' import { leagueCommonPropTypes } from '../constants/leaguePropTypes' export const createLeagueComponent = (leagueConfig) => { const { competitionName, leagueName, flagUrl, alt } = leagueConfig const LeagueComponent = (props) => { // 这里的逻辑和你之前写的单个联赛组件完全一致 const { highlights, areHighlightsLoading, haveHighlightsError, standings, areStandingsLoading, haveStandingsError, scorers, areScorersLoading, haveScorersError, table, tableKey } = props; return ( <div> <League highlights={highlights} areHighlightsLoading={areHighlightsLoading} haveHighlightsError={haveHighlightsError} areStandingsLoading={areStandingsLoading} haveStandingsError={haveStandingsError} scorers={scorers} areScorersLoading={areScorersLoading} haveScorersError={haveScorersError} competitionName={competitionName} leagueName={leagueName} flagUrl={flagUrl} alt={alt} table={table} tableKey={tableKey} /> </div> ) } LeagueComponent.propTypes = leagueCommonPropTypes return LeagueComponent }
之后你要新建任意联赛组件,只需要传入配置即可,一行代码就能生成:
// 生成英超组件 import { createLeagueComponent } from './utils/createLeagueComponent' export const PremierLeague = createLeagueComponent({ competitionName: 'ENGLAND: Premier League', leagueName: 'Premier League', flagUrl: 'https://upload.wikimedia.org/wikipedia/en/a/ae/Flag_of_the_United_Kingdom.svg', alt: 'Flag of United Kingdom' }) // 生成西甲组件 export const LaLiga = createLeagueComponent({ competitionName: 'SPAIN: La Liga', leagueName: 'La Liga', flagUrl: '西班牙国旗资源地址', alt: 'Flag of Spain' })
这种方案的优势是后续新增联赛零重复代码,所有公共逻辑只需要修改工厂函数一处就能全量生效。
方案2:抽离公共逻辑为自定义Hook(适合后续有差异化扩展的场景)
如果后续部分联赛可能有特殊的逻辑处理,可以把通用的props处理、公共propTypes抽成自定义Hook:
// src/hooks/useLeagueCommon.js import { leagueCommonPropTypes } from '../constants/leaguePropTypes' export const useLeagueCommon = (props) => { const { highlights, areHighlightsLoading, haveHighlightsError, standings, areStandingsLoading, haveStandingsError, scorers, areScorersLoading, haveScorersError, table, tableKey } = props // 这里可以放所有联赛通用的逻辑,比如数据格式化、异常处理之类的 return { commonProps: { highlights, areHighlightsLoading, haveHighlightsError, areStandingsLoading, haveStandingsError, scorers, areScorersLoading, haveScorersError, table, tableKey } } } export { leagueCommonPropTypes }
各个联赛组件里直接引用即可:
import { useLeagueCommon, leagueCommonPropTypes } from '../hooks/useLeagueCommon' const PremierLeague = (props) => { const { commonProps } = useLeagueCommon(props) // 这里可以加英超独有的逻辑 const competitionName = 'ENGLAND: Premier League'; const leagueName = 'Premier League'; const flagUrl = '英国国旗资源地址'; const alt = 'Flag of United Kingdom'; return ( <div> <League {...commonProps} competitionName={competitionName} leagueName={leagueName} flagUrl={flagUrl} alt={alt} /> </div> ) } PremierLeague.propTypes = leagueCommonPropTypes
注意点
如果后续有个别联赛需要自定义传递额外参数给League组件,直接在工厂函数或者Hook里加扩展支持即可,不会影响其他联赛的逻辑。
内容的提问来源于stack exchange,提问作者ManuLisek
相关产品推荐
相关产品推荐

