我们现在的需求是:像简书一样一次只显示10个内容,然后通过点击“换一批”按钮,展示下一个10个内容。
1. 定义页码和总页数
我们首先需要在初始状态中定义两个属性:
我们使用 page 属性来控制数据,使用 totalPage 属性来控制总页数。初始状态如下:
当获取数据项时,page 不变,但 total 可能会改变。因此,我们需要在 action 中添加一个参数,并在 setState() 时进行更新:
我们还需要根据 page 和 totalPage 来渲染不同的数据。下面的代码根据 page 来渲染数据。首先,我们需要保证前 10 个数据可以渲染出来:
getListArea(show) {
const {focused, list, page} = this.props;
const newList = list.toJS();
const pageList=[];
for (let i = (page - 1) * 10; i < page * 10; i++) {
pageList.push(
//List是immutable类型,所以需要进行上面的toJS转换为普通数组
<SearchInfoItem key={newList[i]}>{newList[i]}</SearchInfoItem>
)
}
if (show) {
return (
<SearchInfo>
<SearchInfoTitle>
热门搜索
<SearchInfoSwitch>
换一批
</SearchInfoSwitch>
</SearchInfoTitle>
<SearchInfoList>
{pageList}
</SearchInfoList>
</SearchInfo>
)
} else {
return null;
}
};
2. 修复鼠标点击区块隐藏的问题
我们发现区块的隐藏与鼠标移入移出有关,因此需要添加一个控制逻辑,围绕鼠标的移入移出事件,并使用一个属性来表示鼠标是否移入。实际上,这是一个 Redux 流程,这里就不详细介绍了。以下是代码:
然后,我们根据 mouseIn 变量来控制元素的隐藏:
3. 实现“换一批”功能
点击“换一批”按钮,内容会随之更新。首先需要定义一个change事件,在点击“换一批”按钮时触发。该事件需要根据当前的page和totalPage进行判断,更新一个page传给reducer,再由reducer更新一个新的page从而渲染新的页面。以下是代码示例:
handleClickChange(page, totalPage) {
if (page < totalPage) {
dispatch(actionCreators.changePage(page + 1));
} else {
dispatch(actionCreators.changePage(1));
}
}
最后需要解决一下key值的问题。之前我们是用每一个item的名称作为key,但是这里我们发现名称都是不一样的啊?为什么会报key值问题呢?这是因为刚进入页面时,header就会被渲染,此时list是空,page为1,这时渲染会进行,但是list是空数组,所以空数组所有项也是undefined,因此我们可以这样写:
<SearchInfoItem key={i}>{item}</SearchInfoItem>
最后,我们优化一下state的set方法,使用merge可以一次改变多个内容:
return state.merge({
list: fromJS(action.data),
totalPage: action.totalPage
});