实战Header组件:热门搜索栏换一换的功能实现

388 阅读2分钟

我们现在的需求是:像简书一样一次只显示10个内容,然后通过点击“换一批”按钮,展示下一个10个内容。

image.png

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 流程,这里就不详细介绍了。以下是代码:

image.png

image.png

然后,我们根据 mouseIn 变量来控制元素的隐藏:

image.png

3. 实现“换一批”功能

点击“换一批”按钮,内容会随之更新。首先需要定义一个change事件,在点击“换一批”按钮时触发。该事件需要根据当前的pagetotalPage进行判断,更新一个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>

最后,我们优化一下stateset方法,使用merge可以一次改变多个内容:

return state.merge({
  list: fromJS(action.data),
  totalPage: action.totalPage
});