19. 項目實戰(zhàn):首頁開發(fā)(五)

返回頂部功能實現(xiàn)

今天我們要做的是浦辨,回到頂部的功能沼沈。

image.png

我們通過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;
`
我們簡單的實現(xiàn)了這個功能

首頁性能優(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

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市滩褥,隨后出現(xiàn)的幾起案子炫加,更是在濱河造成了極大的恐慌瑰煎,老刑警劉巖俗孝,帶你破解...
    沈念sama閱讀 217,826評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異插勤,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)农尖,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評論 3 395
  • 文/潘曉璐 我一進(jìn)店門良哲,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人筑凫,你說我怎么就攤上這事喇颁『炕酰” “怎么了橘霎?”我有些...
    開封第一講書人閱讀 164,234評論 0 354
  • 文/不壞的土叔 我叫張陵姐叁,是天一觀的道長。 經(jīng)常有香客問我外潜,道長,這世上最難降的妖魔是什么处窥? 我笑而不...
    開封第一講書人閱讀 58,562評論 1 293
  • 正文 為了忘掉前任玄组,我火速辦了婚禮,結(jié)果婚禮上俄讹,老公的妹妹穿的比我還像新娘。我一直安慰自己患膛,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,611評論 6 392
  • 文/花漫 我一把揭開白布胞此。 她就那樣靜靜地躺著跃捣,像睡著了一般漱牵。 火紅的嫁衣襯著肌膚如雪枝缔。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,482評論 1 302
  • 那天愿卸,我揣著相機(jī)與錄音,去河邊找鬼儒溉。 笑死,一個胖子當(dāng)著我的面吹牛顿涣,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播涛碑,決...
    沈念sama閱讀 40,271評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼蒲障!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起揉阎,我...
    開封第一講書人閱讀 39,166評論 0 276
  • 序言:老撾萬榮一對情侶失蹤毙籽,失蹤者是張志新(化名)和其女友劉穎洞斯,沒想到半個月后坑赡,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,608評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡厅翔,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,814評論 3 336
  • 正文 我和宋清朗相戀三年搀突,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片仰迁。...
    茶點故事閱讀 39,926評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡顽分,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出卒蘸,到底是詐尸還是另有隱情,我是刑警寧澤缸沃,帶...
    沈念sama閱讀 35,644評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站趾牧,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏翘单。R本人自食惡果不足惜蹦渣,卻給世界環(huán)境...
    茶點故事閱讀 41,249評論 3 329
  • 文/蒙蒙 一貌亭、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧圃庭,春花似錦、人聲如沸冤议。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,866評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至袱箱,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間发笔,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,991評論 1 269
  • 我被黑心中介騙來泰國打工了讨, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留制轰,地道東北人前计。 一個月前我還...
    沈念sama閱讀 48,063評論 3 370
  • 正文 我出身青樓垃杖,卻偏偏與公主長得像,于是被迫代替她去往敵國和親调俘。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,871評論 2 354