1.我们可以看到,我们现在页面上将从json中获取到的数据全部显示出来,那我们如何做,才能使每次只显示10个?
2.首先在reducer的默认数据中,我们定义一个当前页和一个总页数,都默认为1:
3.在actionCreators中,我们将从json中获取到的数据分成每10个一页。
5.在reducer中,我们接收数据,并将原来的默认的totalPage替换为刚刚action请求的新的数据的页数
6.在index中,我们引入page
7.这一块将数组10个分为一组,显示在页面
8.直接使用pagList
10. 现在,我们如果点击换一换,需要实现热门搜索的换页功能
- 我们首先定义一个鼠标移入的mouseIn,默认是false,也就是鼠标没有移入热门搜索这一块区域
- 在index中,我们给Search这一块的元素绑定两个事件,分别是onMouseEnter和onMouseLeave
- 将刚刚的两个事件派发给store
- 因为使用了actionCreators,所以我们需要在actionCreators定义mouseEnter和mouseLeave
- 然后在actionTypes中添加
- 数据交给reducer处理:如果鼠标移入就将mouseIn改成true,如果移出改为false
- 在index中我们接收mouseIn
- 热门搜索这一块区域的显示由focused以及mouseIn控制
11.点击“换一换”来实现换页功能
- 给SearchInfoSwitch绑定一个onClick点击事件,并传入两个参数page,totalPage
- 从store中获取到tatalPage数据
- 如果当前页page小于总页数,就像store中传递page+1,如果大于,则让page为1
- 创建changePage方法,并将page也传递进来,最后在reducer中去引入
将页数page,重新赋值为最新的值并且返回
这样就实现了所有功能:
index.js代码:
import React, { Component } from 'react';
import iconfont from "../../statics/iconfont/iconfont.css";
import { CSSTransition } from 'react-transition-group';
import { connect } from 'react-redux';
import * as actionCreators from './store/actionCreators';
import {
HeadrerWrapper, Logo, Nav, NavItem,
SearchWrapper,
SearchInfo,
SearchInfoTitle,
SearchInfoList,
SearchInfoItem,
SearchInfoSwitch,
NavSearch,
Addition,
Button,
} from './style'
class Header extends Component{
getListArea() {
const { focused, list, page ,mouseIn,totalPage} = this.props;
//将list转化为js普通数组
const newList = list.toJS();
const pageList = [];
//当列表中有内容时,才会执行
if (newList.length) {
for (let i = ((page-1) * 10); i < (page * 10); i++){
pageList.push(
<SearchInfoItem key={newList[i]} >{newList[i]}</SearchInfoItem>
)
}
}
if(focused ||mouseIn ){
return (
<SearchInfo
onMouseEnter={this.props.handleMouseEnter}
onMouseLeave={this.props.handleMouseLeave}>
<SearchInfoTitle>
热门搜索
<SearchInfoSwitch
onClick={() => { this.props.handleChangePage(page,totalPage) }}
>换一换</SearchInfoSwitch>
</SearchInfoTitle>
<SearchInfoList>
{pageList}
</SearchInfoList>
</SearchInfo>)
} else {
}
}
render() {
return (
<HeadrerWrapper>
<Logo href='/' />
<Nav>
<NavItem className='left active'>首页</NavItem>
<NavItem className='left'>下载App</NavItem>
<NavItem className='right'>登录</NavItem>
<NavItem className='right'>
<i className="iconfont"></i>
</NavItem>
<SearchWrapper>
<CSSTransition
in={this.props.focused}
timeout={200}
classNames="slide"
>
<NavSearch
className={this.props.focused ? 'focused' : ''}
onFocus={this.props.handleInputFocus}
onBlur={this.props.handleInputBlur}
></NavSearch>
</CSSTransition>
<i className={this.props.focused ? 'focused iconfont' : 'iconfont'}></i>
{/*调用getListArea方法,如果聚焦显示*/}
{this.getListArea()}
</SearchWrapper>
</Nav>
<Addition>
<Button className='writting'>
<i className="iconfont"></i>
写文章</Button>
<Button className='reg'>注册</Button>
</Addition>
</HeadrerWrapper>
)
}
}
//mapStateToProps:组件和store做连接的时候,store数据映射如何到props上
const mapStateToProps = (state)=>{
return {
//将store中的focused映射到组件里面
//focused: state.get('header').get('focused')
//还可以通过getIn方法获取到focused
focused: state.getIn(['header', 'focused']),
//我们将获取到的list的数据取出来到原来的list中
list: state.getIn(['header', 'list']),
page: state.getIn(['header', 'page']),
totalPage:state.getIn(['header','totalPage']),
mouseIn:state.getIn(['header','mouseIn'])
}
}
//组件想要改变store的内容需要调用的方法
const mapDispathToProps = (dispatch)=>{
return{
handleInputFocus(){
// const action = {
// type:'search_focus'
// }
//派发一个getList方法获取数据
dispatch(actionCreators.getList())
dispatch( actionCreators.searchFocus());
},
handleInputBlur() {
// const action ={
// type:'search_blur'
// }
dispatch(actionCreators.searchBlur());
},
handleMouseEnter(){
dispatch(actionCreators.mouseEnter());
},
handleMouseLeave() {
dispatch(actionCreators.mouseLeave());
},
handleChangePage(page, totalPage) {
if (page < totalPage) {
dispatch(actionCreators.changePage(page+1));
} else {
dispatch(actionCreators.changePage(1));
}
}
}
}
export default connect(mapStateToProps,mapDispathToProps)(Header);
reducer.js代码:
import * as actionTypes from './actionTypes';
import { fromJS } from 'immutable';
const defaultState =fromJS({
focused: false,
mouseIn: false,
list: [],
//page表示当前页,totalPage表示总页数
page: 1,
totalPage: 1
});
export default (state=defaultState,action) => {
// if (action.type === 'search_focus') {
if(action.type===actionTypes.SEARCH_FOCUS){
// return {
// focused:true
// }
//immutable对象的set方法,会结合之前immutable对象的值和设置的值
//返回一个新的对象,并没有对之前的进行修改
return state.set('focused', true);
};
if (action.type === actionTypes.SEARCH_BLUR) {
return state.set('focused', false);
};
if (action.type === actionTypes.CHANGE_LIST) {
//将原来的数据的list改成我们现在请求的data
return state.set('list',action.data).set('totalPage',action.totalPage)
};
if(action.type === actionTypes.MOUSE_ENTER){
return state.set('mouseIn', true);
};
if(action.type === actionTypes.MOUSE_LEAVE){
return state.set('mouseIn', false);
};
if (action.type === actionTypes.CHANGE_PAGE) {
return state.set('page', action.page);
}
return state;
}
actionCreators代码:
import * as actionTypes from './actionTypes';
import { fromJS } from 'immutable';
import axios from 'axios';
export const searchFocus = () => ({
type:actionTypes.SEARCH_FOCUS
});
export const searchBlur = () => ({
type:actionTypes.SEARCH_BLUR
});
export const mouseEnter = () => ({
type: actionTypes.MOUSE_ENTER
});
export const mouseLeave = () => ({
type:actionTypes.MOUSE_LEAVE
});
export const changePage=(page)=>({
type: actionTypes.CHANGE_PAGE,
page
})
//定义changeList,给getList使用,在getList派发changeList请求修改
const changeList = (data) =>( {
type: actionTypes.CHANGE_LIST,
//将data数据也改为immutable类型
data: fromJS(data),
//将获取到的数据10个分在一页,totalPage表示总页数
totalPage:Math.ceil(data.length/10)
})
export const getList = () => {
return (dispatch) => {
axios.get('/api/headerList.json').then((res) => {
//将获取到的res的data数据传递给现在定义的data,并输出data
const data = res.data;
//拿到需要修改的data数据下面的data派发给store
dispatch(changeList(data.data));
}).catch(() => {
console.log('error');
})
}
}