11.热门搜索中数据换一批功能19-06-14

2019-06-14  本文已影响0人  你坤儿姐

代码见https://gitee.com/XiaoKunErGe/JianShu.git历史版本第13次提交。
一.首先要让鼠标移到搜索弹出框范围内时,弹出框不隐藏
1.在header下的reducer中,添加一个新的值mouseIn初始值设为false

  const defaultState = fromJS({
  focused: false,
  list:[],
  mouseIn:false
});

2.到header下的index中的<SearchInfo/>组件中添加两个方法,既鼠标移入移出的方法

<SearchInfo
         onMouseEnter={handleMouseEnter}
         onMouseLeave={handleMouseLeave}
      >

在mapDispatchToProps将事件传给store
constants.js添加代码

export const MOUSE_ENTER = 'header/MOUSE_ENTER';
export const MOUSE_LEAVE = 'header/MOUSE_LEAVE';

actionCreators.js添加代码

export const mouseEnter = () => ({
  type: constants.MOUSE_ENTER
});
export const mouseLeave = () => ({
  type: constants.MOUSE_LEAVE
});

到reducer中处理事件并将响应事件反应给用户
reducer.js中的代码

case constants.MOUSE_ENTER:
      return state.set('mouseIn', true);
    case constants.MOUSE_LEAVE:
      return state.set('mouseIn', false);

到mapStateToProps中接收mouseIn值并用以限制<SearchInfo/>组件是否显示

 mouseIn: state.getIn(['header', 'mouseIn']),
 if (focused ||mouseIn ){
      return(
        <SearchInfo
           onMouseEnter={handleMouseEnter}
           onMouseLeave={handleMouseLeave}
        >
          <SearchInfoTittle>
            热门搜索
            <SearchInfoSwitch onClick={()=> handelChangePage(page, totalPage)}>换一批</SearchInfoSwitch>
          </SearchInfoTittle>
          <SearchInfoList>
            {先别管这儿}
          </SearchInfoList>
        </SearchInfo>
      )
    }else {
      return null;
    }
  }

二.实现换一批功能
1.到reducer中添加两个值,page(当前显示的页数),totalPage(一共多少页)

const defaultState = fromJS({
  focused: false,
  list:[],
  mouseIn:false,
  page: 1,
  totalPage:1
});

2.到mapStateToProps处获取page值

page: state.getIn(['header', 'page']),

3.删除之前<SearchInfoItem/>组件的方法,将<SearchInfoItem/>方法拿出来,改写在getListArea()方法下
a. ######在这里拿到list数据,并将其immutable转换成JS类型,因为immutable类型无法使用list[ i ]这种语法取值。

const newList = list.toJS();

b.建一个空数组用来放每页显示的数据

const pageList = [];

c.添加for循环为每一页的Item显示数据

for(let i = (page-1)*10 ;i < page *10 ; i++){
//初始值page不能设置为0,因为 i < page *10,设置为零for循环不走
//10是要求每页显示10个Item
        pageList.push(
           <SearchInfoItem key={newList[i]}>{newList[i]}</SearchInfoItem>
         )
      }

这时存在一个问题就是,如果你的数据个数不是10的倍数,运行到最后一组数据时,就会报一个key值不存在的错,这时需要加以判断

if ( page*10 < newList.length ){
//当循环数据数小于数据总量是,也就是不是最后一组数据时循环  (page-1)*10 到 10*page 的数次,既10次
      for(let i = (page-1)*10 ;i < page *10 ; i++){
         pageList.push(
           <SearchInfoItem key={newList[i]}>{newList[i]}</SearchInfoItem>
         )
      }
    }else {
//当循环数据数大于数据总量是,也就是是最后一组数据时循环  (page-1)*10 到 newList.length的数次,既(newList.length - (page-1)*10)次
      for(let i = (page-1)*10 ;i < newList.length; i++){
        pageList.push(
          <SearchInfoItem key={newList[i]}>{newList[i]}</SearchInfoItem>
        )
      }
    }

在SearchInfoList中调用以上方法

 <SearchInfoList>
    {pageList}
 </SearchInfoList>

d.这时运行项目,只显示一组10个数据,因为我们传的page值是固定的只有一个。接下来改变数据,实现‘换一批’功能。

这里要获取总共页数

在action传递list给reducer的代码中(actionCreators的changeList中),添加一个值totalPage

export const changeList = (data) => ({
  type: constants.CHANGE_LIST,
  data:fromJS(data),
  totalPage: Math.ceil(data.length / 10)
//data.length是获取的list值个数,10是每页要求显示多少个,Math.ceil是取整。
});

到reducer中返回数据

 case constants.CHANGE_LIST:
      return state.set('list', action.data).set('totalPage', action.totalPage);

到index.js中mapStateToProps中接收数据

totalPage: state.getIn(['header', 'totalPage'])

这时在index中就拿到了总共显示的页数。
e.到 ‘换一批’ 组件处添加handelChangePage方法,将page值判断后传给sore

 <SearchInfoSwitch onClick={()=> handelChangePage(page, totalPage) }>换一批</SearchInfoSwitch>

在mapDispatchToProps中实现方法

handelChangePage(page, totalPage) {
      if (page < totalPage){
        dispatch(actionCreators.changePage(page+1))
      }else{
//页数大于总页数时显示开始从第一页显示
        dispatch(actionCreators.changePage(1))
      }
    }

到这里就结束了。
整理代码:

export default (state = defaultState, action) => {
  switch(action.type) {
    case constants.SEARCH_FOCUS:
      return state.set('focused', true);
    case constants.SEARCH_BLUR:
      return state.set('focused', false);
    case constants.CHANGE_LIST:
      return state.merge({
        //merge可以同时改变多个数据内容,相当于多次调用set,比set性能更高
        list: action.data,
        totalPage: action.totalPage
      })
    case constants.MOUSE_ENTER:
      return state.set('mouseIn', true);
    case constants.MOUSE_LEAVE:
      return state.set('mouseIn', false);
    case constants.CHANGE_PAGE:
       return state.set('page', action.page);
    default:
     return state
  }
};

注意:不要忘了要把所有接收的数据和方法都添加在this.props里
const { focused,mouseIn,list,page,totalPage,handelChangePage,handleMouseEnter,handleMouseLeave } = this.props;

上一篇下一篇

猜你喜欢

热点阅读