回到顶部的功能,因为代码量很少,因此就不将他单独拆分为一个js 文件了。我们在src/pages/home 下的index 中写它。
index 如下。
import React, {Component} from 'react';
import { connect } from 'react-redux';
import {HomeWrapper, HomeLeft, HomeRight, BackTop } from './style';
import List from './components/List';
import Recommend from './components/Recommend';
import Topic from './components/Topic';
import Writer from './components/Writer';
import bannerImage from '../../statics/ooo.jpg';
import { actionCreators } from './store';
class Home extends Component {
render () {
return (
<HomeWrapper>
<HomeLeft>
<img
className="banner-img"
src={bannerImage}
alt=''
/>
<Topic></Topic>
<List></List>
</HomeLeft>
<HomeRight>
<Recommend></Recommend>
<Writer></Writer>
</HomeRight>
<BackTop>回到顶部</BackTop>
</HomeWrapper>
)
}
componentDidMount () {
this.props.changeHomeData();
}
}
const mapDispatch = (dispatch) => {
return {
changeHomeData () {
const action = actionCreators.getHomeInfo();
dispatch(action);
}
}
}
export default connect(null, mapDispatch)(Home);
然后在 style.js 中定义一下,如下。
然后在 index 中定义一下点击“顶部” 的click 事件,如下。
import React, {Component} from 'react';
import { connect } from 'react-redux';
import {HomeWrapper, HomeLeft, HomeRight, BackTop } from './style';
import List from './components/List';
import Recommend from './components/Recommend';
import Topic from './components/Topic';
import Writer from './components/Writer';
import bannerImage from '../../statics/ooo.jpg';
import { actionCreators } from './store';
class Home extends Component {
handleScrollTop () {
window.scrollTo(0,0);
}
render () {
return (
<HomeWrapper>
<HomeLeft>
<img
className="banner-img"
src={bannerImage}
alt=''
/>
<Topic></Topic>
<List></List>
</HomeLeft>
<HomeRight>
<Recommend></Recommend>
<Writer></Writer>
</HomeRight>
<BackTop onClick={this.handleScrollTop}>顶部</BackTop>
</HomeWrapper>
)
}
componentDidMount () {
this.props.changeHomeData();
}
}
const mapDispatch = (dispatch) => {
return {
changeHomeData () {
const action = actionCreators.getHomeInfo();
dispatch(action);
}
}
}
export default connect(null, mapDispatch)(Home);
然后,再实现一下,在页面回到顶部的时候,这个小组件就没了,往下翻就会出现。
这个我们通过一个变量保存,它的出现和隐藏。打开 src/pages/home/store 下的 reducer
import { fromJS } from 'immutable';
import * as actionTypes from './actionTypes';
const defaultState = fromJS({
topicList: [],
articleList: [],
recommendList: [],
articlePage: 1,
showScroll: false
});
export default (state = defaultState, action) => {
switch (action.type) {
case actionTypes.CHANGE_HOME_DATA:
return state.merge({
"topicList": fromJS(action.topicList),
"articleList": fromJS(action.articleList),
"recommendList": fromJS(action.recommendList)
});
case actionTypes.ADD_ARTICLE_LIST:
return state.merge({
"articleList": state.get("articleList").concat(action.articleList),
"articlePage": action.page
})
default:
return state;
}
}
然后,我们在src/pages/home 下的 index 中做初始化,如下。
import React, {Component} from 'react';
import { connect } from 'react-redux';
import {HomeWrapper, HomeLeft, HomeRight, BackTop } from './style';
import List from './components/List';
import Recommend from './components/Recommend';
import Topic from './components/Topic';
import Writer from './components/Writer';
import bannerImage from '../../statics/ooo.jpg';
import { actionCreators } from './store';
class Home extends Component {
handleScrollTop () {
window.scrollTo(0,0);
}
render () {
return (
<HomeWrapper>
<HomeLeft>
<img
className="banner-img"
src={bannerImage}
alt=''
/>
<Topic></Topic>
<List></List>
</HomeLeft>
<HomeRight>
<Recommend></Recommend>
<Writer></Writer>
</HomeRight>
{this.props.showScroll ? <BackTop onClick={this.handleScrollTop}>顶部</BackTop> : null }
</HomeWrapper>
)
}
componentDidMount () {
this.props.changeHomeData();
}
}
const mapState = (state) => {
return {
showScroll: state.get("home").get("showScroll")
}
}
const mapDispatch = (dispatch) => {
return {
changeHomeData () {
const action = actionCreators.getHomeInfo();
dispatch(action);
}
}
}
export default connect(mapState, mapDispatch)(Home);
上面我们只是把初始进来的时候隐藏“顶部” 按钮。下面,我们来写,当页面不是顶部的时候,显示“顶部”按钮。如下是 index。
import React, {Component} from 'react';
import { connect } from 'react-redux';
import {HomeWrapper, HomeLeft, HomeRight, BackTop } from './style';
import List from './components/List';
import Recommend from './components/Recommend';
import Topic from './components/Topic';
import Writer from './components/Writer';
import bannerImage from '../../statics/ooo.jpg';
import { actionCreators } from './store';
class Home extends Component {
handleScrollTop () {
window.scrollTo(0,0);
}
render () {
return (
<HomeWrapper>
<HomeLeft>
<img
className="banner-img"
src={bannerImage}
alt=''
/>
<Topic></Topic>
<List></List>
</HomeLeft>
<HomeRight>
<Recommend></Recommend>
<Writer></Writer>
</HomeRight>
{this.props.showScroll ? <BackTop onClick={this.handleScrollTop}>顶部</BackTop> : null }
</HomeWrapper>
)
}
componentDidMount () {
this.props.changeHomeData();
this.bindEvents();
}
bindEvents() {
window.addEventListener("scroll", this.props.changeScrollTopShow);
}
}
const mapState = (state) => {
return {
showScroll: state.get("home").get("showScroll")
}
}
const mapDispatch = (dispatch) => {
return {
changeHomeData () {
const action = actionCreators.getHomeInfo();
dispatch(action);
},
changeScrollTopShow () {
console.log();
if ( document.documentElement.scrollTop > 100) {
dispatch(actionCreators.toggleShowScroll(true));
} else {
dispatch(actionCreators.toggleShowScroll(false));
}
}
}
}
export default connect(mapState, mapDispatch)(Home);
然后在 actionCreators 中添加 toogleShowScroll
import axios from 'axios';
import { fromJS } from 'immutable';
import * as actionTypes from './actionTypes';
const changeHomeData = (result) => ({
type: actionTypes.CHANGE_HOME_DATA,
topicList: result.topicList,
articleList: result.articleList,
recommendList: result.recommendList
});
const addHomeList = (result, page) => ({
type: actionTypes.ADD_ARTICLE_LIST,
articleList: fromJS(result.articleList),
page: page
})
export const getHomeInfo = () => {
return (dispatch) => {
axios.get("/api/home.json").then((res) => {
const result = res.data.data;
const action = changeHomeData(result);
dispatch(action);
});
}
}
export const getMoreList = (page) => {
return (dispatch) => {
axios.get("/api/homeList.json?page=" + page).then((res) => {
const result = res.data.data;
const action = addHomeList(result, page + 1);
dispatch(action);
})
}
}
export const toggleShowScroll = (show) => ({
type: actionTypes.TOGGLE_SCROLL_SHOW,
show: show
})
最后,往 reducer 中添加一个case
import { fromJS } from 'immutable';
import * as actionTypes from './actionTypes';
const defaultState = fromJS({
topicList: [],
articleList: [],
recommendList: [],
articlePage: 1,
showScroll: false
});
export default (state = defaultState, action) => {
switch (action.type) {
case actionTypes.CHANGE_HOME_DATA:
return state.merge({
"topicList": fromJS(action.topicList),
"articleList": fromJS(action.articleList),
"recommendList": fromJS(action.recommendList)
});
case actionTypes.ADD_ARTICLE_LIST:
return state.merge({
"articleList": state.get("articleList").concat(action.articleList),
"articlePage": action.page
});
case actionTypes.TOGGLE_SCROLL_SHOW:
return state.set("showScroll", action.show);
default:
return state;
}
}
注意一点,我们在index 中写的是,当组件挂载后,会往 window 中绑定一个scroll 事件。我们一定别忘记了,当这个组件被从页面移除的时候,一定要把window 的scroll 事件也移除。
import React, {Component} from 'react';
import { connect } from 'react-redux';
import {HomeWrapper, HomeLeft, HomeRight, BackTop } from './style';
import List from './components/List';
import Recommend from './components/Recommend';
import Topic from './components/Topic';
import Writer from './components/Writer';
import bannerImage from '../../statics/ooo.jpg';
import { actionCreators } from './store';
class Home extends Component {
handleScrollTop () {
window.scrollTo(0,0);
}
render () {
return (
<HomeWrapper>
<HomeLeft>
<img
className="banner-img"
src={bannerImage}
alt=''
/>
<Topic></Topic>
<List></List>
</HomeLeft>
<HomeRight>
<Recommend></Recommend>
<Writer></Writer>
</HomeRight>
{this.props.showScroll ? <BackTop onClick={this.handleScrollTop}>顶部</BackTop> : null }
</HomeWrapper>
)
}
componentDidMount () {
this.props.changeHomeData();
this.bindEvents();
}
bindEvents() {
window.addEventListener("scroll", this.props.changeScrollTopShow);
}
componentWillUnmount () {
window.removeEventListener("scroll", this.props.changeScrollTopShow);
}
}
const mapState = (state) => {
return {
showScroll: state.get("home").get("showScroll")
}
}
const mapDispatch = (dispatch) => {
return {
changeHomeData () {
const action = actionCreators.getHomeInfo();
dispatch(action);
},
changeScrollTopShow () {
console.log();
if ( document.documentElement.scrollTop > 100) {
dispatch(actionCreators.toggleShowScroll(true));
} else {
dispatch(actionCreators.toggleShowScroll(false));
}
}
}
}
export default connect(mapState, mapDispatch)(Home);
Done.