面试题答案
一键面试设计思路
- 样式方面:
- 使用 CSS 模块或 styled - components 来处理样式。通过传递样式相关的 props 来实现不同应用的样式定制。例如,对于列表项的背景颜色、字体大小等,组件接收
itemBackgroundColor
,itemFontSize
等 props。这样可以在不同应用中轻松覆盖默认样式。 - 采用装饰器模式,将样式逻辑分离出来。可以创建一个样式装饰器函数,该函数接收一个 React 组件作为参数,并返回一个新的带有特定样式的组件。比如:
在列表组件中,可以使用这个装饰器来添加基础样式,不同应用如果有特殊样式需求,可以再次使用装饰器或者通过 props 传递样式覆盖。import React from'react'; const withListItemStyle = (WrappedComponent) => { return (props) => { return ( <div style={{ backgroundColor: 'lightgray', padding: '10px' }}> <WrappedComponent {...props} /> </div> ); }; }; export default withListItemStyle;
- 使用 CSS 模块或 styled - components 来处理样式。通过传递样式相关的 props 来实现不同应用的样式定制。例如,对于列表项的背景颜色、字体大小等,组件接收
- 交互逻辑方面:
- 采用策略模式,将不同的交互逻辑抽象成策略函数。例如,点击列表项的逻辑,不同应用可能有不同处理,一个应用可能是跳转到详情页,另一个应用可能是显示一个弹窗。
- 在列表组件中,定义一个
onItemClick
的 prop,接收一个函数作为参数。不同应用在使用该列表组件时,传递符合自身业务的点击处理函数。如下示例:
const ListComponent = ({ items, onItemClick }) => { return ( <ul> {items.map((item, index) => ( <li key={index} onClick={() => onItemClick(item)}> {item.text} </li> ))} </ul> ); };
- 数据获取方式方面:
- 列表组件不直接负责数据获取,而是通过 props 接收数据。这样不同应用可以根据自身的数据获取逻辑(如通过 API 调用、本地存储读取等)获取数据后传递给列表组件。
- 可以提供一个
fetchData
的 prop,接收一个异步函数。该函数负责获取数据并返回 Promise。在列表组件的componentDidMount
(类组件)或useEffect
(函数组件)中调用这个fetchData
函数来获取数据。例如:
import React, { useEffect, useState } from'react'; const ListComponent = ({ fetchData }) => { const [items, setItems] = useState([]); useEffect(() => { const fetch = async () => { const data = await fetchData(); setItems(data); }; fetch(); }, [fetchData]); return ( <ul> {items.map((item, index) => ( <li key={index}>{item.text}</li> ))} </ul> ); }; export default ListComponent;
整体架构设计
- 组件结构:
- 创建一个基础的
ListBase
组件,负责处理列表的基本渲染逻辑,如循环渲染列表项等。 - 通过装饰器模式,对
ListBase
组件进行样式装饰,生成带有默认样式的StyledList
组件。 - 在不同应用中,根据需求进一步通过 props 定制
StyledList
组件的样式、交互逻辑和数据获取方式。
- 创建一个基础的
- 代码示例:
- ListBase.js
import React from'react'; const ListBase = ({ items }) => { return ( <ul> {items.map((item, index) => ( <li key={index}>{item.text}</li> ))} </ul> ); }; export default ListBase;
- styles.js(样式装饰器)
import React from'react'; const withListItemStyle = (WrappedComponent) => { return (props) => { return ( <div style={{ backgroundColor: 'lightgray', padding: '10px' }}> <WrappedComponent {...props} /> </div> ); }; }; export default withListItemStyle;
- StyledList.js
import ListBase from './ListBase'; import withListItemStyle from './styles'; const StyledList = withListItemStyle(ListBase); export default StyledList;
- 在应用中使用
import React, { useEffect, useState } from'react'; import StyledList from './StyledList'; const fetchData = async () => { // 模拟数据获取 return [ { text: 'Item 1' }, { text: 'Item 2' } ]; }; const onItemClick = (item) => { console.log(`Clicked on ${item.text}`); }; const App = () => { return ( <StyledList fetchData={fetchData} onItemClick={onItemClick} /> ); }; export default App;
通过以上设计,列表组件可以在不同业务的 React 应用中高度适配,满足不同的样式、交互逻辑和数据获取需求。