返回頂部功能實現(xiàn)
今天我們要做的是浦辨,回到頂部的功能沼沈。
我們通過reducer中showScroll這個屬性判斷是否顯示這個按鈕列另,那什么時候觸發(fā)showScroll屬性的改變呢?我們在生命周期鉤子函數(shù)掛載組件的時候綁定window的滑動監(jiān)聽事件页衙,卸載前解綁這個事件就可以了阴绢。數(shù)據(jù)的改變我們使用的redux。
1.添加一個用來分發(fā)scroll事件的action常量
//===>src/pages/home/store/constants.js
export const CHANGE_HOME_DATA = 'home/CHANGE_HOME_DATA'
export const ADD_ARTICLE_LIST = 'home/ADD_ARTICLE_LIST'
export const TOGGLE_SCROLL_TOP = 'home/TOGGLE_SCROLL_TOP'
2.編寫actionCreators.js
//===>src/pages/home/store/actionCreators.js
...
export const toggleTopShow = (show) => ({
type: constants.TOGGLE_SCROLL_TOP,
show
})
3.編寫reducer.js
import { fromJS } from 'immutable';
import * as constants from './constants'
const defaultState = fromJS({
topicList: [],
articleList: [],
recommendList: [],
articlePage: 1,
showScroll: false
});
export default (state = defaultState, action) => {
switch (action.type) {
...
case constants.TOGGLE_SCROLL_TOP:
return state.set('showScroll', action.show)
default:
return state;
}
}
4.接下來我們把這個按鈕寫在Home組件中
//===>src/pages/home/index.js
import React, { Component } from 'react'
import { HomeWrapper, HomeLeft, HomeRight, BackTop } from './style'
import Topic from './components/Topic'
import List from './components/List'
import Recommend from './components/Recommend'
import Writer from './components/Writer'
import { connect } from 'react-redux'
import { actionCreators } from './store'
class Home extends Component {
handleScrollTop() {
window.scrollTo(0, 0)
}
render() {
return (
<HomeWrapper>
<HomeLeft>
<img className="banner-img" src="https://upload.jianshu.io/admin_banners/web_images/4993/421ec96ccef8aea708c84ba2972b5be484695f25.png?imageMogr2/auto-orient/strip|imageView2/1/w/1250/h/540" alt='' />
<Topic />
<List />
</HomeLeft>
<HomeRight>
<Recommend />
<Writer />
</HomeRight>
{
this.props.showScroll ?
<BackTop onClick={this.handleScrollTop}>回到</BackTop>
: null
}
</HomeWrapper>
)
}
componentDidMount() {
this.props.changeHomeData()
this.bindEvents()
}
componentWillUnmount() {
window.removeEventListener('scroll', this.props.changeScrollTop)
}
bindEvents() {
window.addEventListener('scroll', this.props.changeScrollTop)
}
}
const mapDispatch = (dispatch) => ({
changeHomeData() {
const action = actionCreators.getHomeInfo()
dispatch(action)
},
changeScrollTop() {
if (document.documentElement.scrollTop > 100) {
dispatch(actionCreators.toggleTopShow(true))
} else {
dispatch(actionCreators.toggleTopShow(false))
}
}
})
const mapState = (state) => ({
showScroll: state.getIn(['home', 'showScroll'])
})
export default connect(mapState, mapDispatch)(Home)
5.最后寫backTop的樣式
//===>src/pages/home/style.js
...
export const BackTop = styled.div`
position:fixed;
right:100px;
bottom:100px;
width:60px;
height:60px;
line-height:60px;
text-align:center;
border:1px solid #ccc;
font-size:14px;
`
首頁性能優(yōu)化及路由跳轉(zhuǎn)
兩個功能
1.點擊列表的item,跳轉(zhuǎn)到詳情頁
2.點擊左上角的Logo廉侧,返回首頁
1.為List組件的item增加路由跳轉(zhuǎn)功能。我們的路由是組件化跳轉(zhuǎn)段誊,不需要url的重新請求栈拖,所以用的是react-router-dom三方模塊的Link
...
import { Link } from 'react-router-dom'
class List extends PureComponent {
render() {
const { list, page, getMoreList } = this.props
return (
<div>
{
list.map((item, index) => {
return (
<Link key={index} to='/detail'>
<ListItem key={index}>
...
</ListItem>
</Link>
)
})
}
...
</div>
)
}
}
...
詳情頁面的跳轉(zhuǎn)實現(xiàn)了。
2.我們來寫一下Logo的跳主頁辱魁。
(1)我們先改一下之前header組件的style
我們?nèi)サ袅酥暗腶ttr屬性href,把a(bǔ)標(biāo)簽換成了div染簇。
//===>src/common/header/style.js
...
export const Logo = styled.div`
position:absolute;
top:0;
left:0;
display:block;
width:100px;
height:56px;
background:url(${logoPic});
background-size:contain;
`
...
(2)在Header組件添加Link
...
import { Link } from 'react-router-dom'
class Header extends Component {
...
render() {
const { focused, handleInputFocus, handleInputBlur, list } = this.props
return (
<Fragment>
<IconFontStyle />
<HeaderWrapper>
<Link to='/'>
<Logo />
</Link>
...
</HeaderWrapper>
</Fragment>
)
}
}
...
還要改一個地方,之前Header組件和下面裝Home組件和Detail組件的容器BrowserRouter是兄弟關(guān)系锻弓,所以不能用Link組件,我們要把他改成父子組件
//===>src/App.js
import React from 'react';
import Header from './common/header'
import store from './store'
import { Provider } from 'react-redux'
import { BrowserRouter, Route } from 'react-router-dom'
import Home from './pages/home';
import Detail from './pages/detail'
function App() {
return (
<Provider store={store}>
<BrowserRouter>
<div>
<Header />
<Route path='/' exact component={Home}></Route>
<Route path='/detail' exact component={Detail}></Route>
</div>
</BrowserRouter>
</Provider >
);
}
export default App;
點擊Logo暴心,我們可以回到首頁杂拨。
還有一個優(yōu)化专普,如果數(shù)據(jù)發(fā)生一點改變弹沽,renter(){}就會渲染整個組件筋粗,這很費性能炸渡,是不合理的娜亿。我們希望只渲染數(shù)據(jù)有變化的組件蚌堵。解決方案是,如果我們用了immutable數(shù)據(jù)類型吼畏,那么我們只需要把Component改成PureComponent就好了。
操作方法是:1.導(dǎo)入import React, { PureComponent } from 'react'
2.把Home够挂、Topic、List、Recommend枯冈、Writer中的Component變成PureComponent