热门搜索换页功能实现
这次,我们想实现一个,点击“换一批”按钮,下面的数据就会分组刷新的功能。
我们修改了模拟接口,把数据改成了20个,然后增加了totalPage(总页数字段)和page(当前页字段),一边数组数据是个一组的分包。
这一节改动的地方比较多,比较零散,但是围绕着redux进行的,没有什么难度。所以我仅仅贴出了代码。
1.增加要用到的action的type常量
//===>src/common/header/store/constants.js
...
export const MOUSE_ENTER = 'header/MOUSE_ENTER'
export const MOUSE_LEAVE = 'header/MOUSE_LEAVE'
export const CHANGE_PAGE = 'header/CHANGE_PAGE'
2.编写相关功能的actionCreators.js
//===>src/common/header/store/actionCreators.js
import * as constants from './constants'
import axios from 'axios'
import { fromJS } from 'immutable'
...
export const mouseEnter = () => ({
type: constants.MOUSE_ENTER
})
export const mouseLeave = () => ({
type: constants.MOUSE_LEAVE
})
export const changePage = (page) => ({
type: constants.CHANGE_PAGE,
page
})
const changeList = (data) => ({
type: constants.CHANGE_LIST,
data: fromJS(data),
totalPage: Math.ceil(data.length / 10)
})
...
3.在reducer里改变数据
state.merge({})可以实现多个数据一起改。
//===>src/common/header/store/reducer.js
import * as constants from './constants'
import { fromJS } from 'immutable'
const defaultState = fromJS({
focused: false,
mouseIn: false,
list: [],
page: 1,
totalPage: 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({
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
}
}
4.最后,还是要贴出Header组件的全代码
//===>src/common/header/index.js
import React, { Component, Fragment } from 'react'
import { CSSTransition } from 'react-transition-group'
import {
HeaderWrapper,
Logo,
Nav,
NavItem,
SearchWrapper,
NavSearch,
SearchInfo,
SearchInfoTitle,
SearchInfoSwitch,
SearchInfoList,
SearchInfoItem,
Addition,
Button
} from './style'
import { IconFontStyle } from '../../statics/iconfont/iconfont';
import { connect } from 'react-redux';
import { actionCreators } from './store';
class Header extends Component {
getListArea() {
const { focused, list, page, totalPage, mouseIn, handleMouseEnter, handleMouseLeave, handleChangePage } = this.props
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={handleMouseEnter}
onMouseLeave={handleMouseLeave}>
<SearchInfoTitle>
热门搜索
<SearchInfoSwitch onClick={() => handleChangePage(page, totalPage)}>换一批</SearchInfoSwitch>
</SearchInfoTitle>
<SearchInfoList>
{pageList}
</SearchInfoList>
</SearchInfo>
)
} else {
return null;
}
}
render() {
const { focused, handleInputFocus, handleInputBlur } = this.props
return (
<Fragment>
<IconFontStyle />
<HeaderWrapper>
<Logo />
<Nav>
<NavItem className='left'>首页</NavItem>
<NavItem className='left'>下载App</NavItem>
<NavItem className='right'>登录</NavItem>
<NavItem className='right'>
<span className="iconfont"></span>
</NavItem>
<SearchWrapper>
<CSSTransition
in={focused}
timeout={200}
classNames="slide">
<NavSearch
className={focused ? 'focused' : ''}
onFocus={handleInputFocus}
onBlur={handleInputBlur}>
</NavSearch>
</CSSTransition>
<span className={focused ? 'focused iconfont' : 'iconfont'}></span>
{this.getListArea()}
</SearchWrapper>
<Addition>
<Button className='writting'>
<span className="iconfont"></span>写文章
</Button>
<Button className='reg'>注册</Button>
</Addition>
</Nav>
</HeaderWrapper>
</Fragment>
)
}
}
const mapStateToProps = (state) => {
return {
// focused: state.get('header').get('focused')
focused: state.getIn(['header', 'focused']),
list: state.getIn(['header', 'list']),
page: state.getIn(['header', 'page']),
totalPage: state.getIn(['header', 'totalPage']),
mouseIn: state.getIn(['header', 'mouseIn'])
}
}
const mapDispatchToProps = (dispatch) => {
return {
handleInputFocus() {
dispatch(actionCreators.getList())
dispatch(actionCreators.searchFocus())
},
handleInputBlur() {
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, mapDispatchToProps)(Header)
网友评论