奇技指南
本文内容主要是我之前分享的文字版,若想看重点的话可以看之前的Slide: https://ppt.baomitu.com/d/75fc979a
本文作者奇舞团前端开发工程师李喆明。
需求描述
由于作者所在的业务是资讯内容类业务,因而在业务中会经常碰到如下场景:有一个内容列表,列表中需要按照一定的规则插入广告。除了获取广告数据,广告展现和点击后需要有打点上报逻辑。正常来说会这么写:
import React from 'react';
export default class extends React.Component {
state = {
newsData: [], adData: []};
constructor() {
this.getNewsData(); }
getNewsData() {
const newsData = [...];
this.setState({
newsData});
this.getAdData(newsData.length / 2); //根据新闻数和插入规则换算广告请求数
}
getAdData() {
const adData = [...];
this.setState({
adData});
}
render() {
const {
newsData, adData} = this.state;
const comps = [];
for(let i = 0; i < newsData.length; i++) {
// 根据插入规则判断当前新闻卡片后是否要插入广告
comps.push(<NewsCard {
...newsData[i]} key={
`news-${
i}`} />);
if(i % 2) {
comps.push(<AdCard {
...adData[i/2]} key={
`ad-${
i}`} />); }
}
return (<div>{
comps}</div>);
}
}
class AdCard extends React.Component {
componentDidMount() {
observe(this.dom, () => {
});
}
onClick = () => {
};
onMouseUp = () => {
};
onMouseDown = () => {
};
getDOM = dom => this.dom = dom;
render() {
return <div
ref={
this.getDOM}
onMouseUp={
this.onMouseUp}
onMouseDown={
this.onMouseDown}
onClick={
this.onClick}
>{
this.props.title}</div>
}
}
逻辑非常的简单,getNewsData() 拿到资讯列表数据之后计算需要请求的广告数调用 getAdData()请求广告数据,最后根据插入规则将资讯和内容渲染到列表中。广告使用自定义组件渲染,使用 Intersection Observe API 实现广告曝光打点,监听 DOM 对应的点击时间实现广告点击打点。
![cf47d712779df7faf4e3edc4412a5480.png](https://img-blog.csdnimg.cn/img_convert/cf47d712779df7faf4e3edc4412a5480.png)
React 组件设计模式
在具体讨论方案之前,我们先简单的了解一下常见的 React 组件设计模式。基本上分为以下几种方案:- Context 模式
- 组合组件
- 继承模式
容器组件和展示组件
Render Props
- Hoc 高阶组件
其中 Context 模式多用来在多层嵌套组件中进行跨组件的数据传递,针对我们当前组件层级不多的情况用处不是非常大,这里就不多表。我们来看看剩下的几个模式各自有什么优缺点,最终来评估下是否能应用到我们的场景中。
组合组件
组合组件是通过