2-3 首页专题区域及reducer 的设计

专题组件,就是 src/pages/home/components 下的Topic.js 。里面的内容如下。

import React, {Component} from 'react';

class Topic extends Component {
    render () {
        return (
            <div>Topic</div>
        )
    }
}

export default Topic;

由于Topic 组件是一个小组件,我们将它的样式,放在home 目录下的style.js 中,和其它小组件的样式放一起管理。

先我们来写一下Topic.js 最简单的结构如下。

import React, {Component} from 'react';
import { TopicWrapper, TopicItem } from '../style';
import smallPic from '../../../statics/pengium.jpg';

class Topic extends Component {
    render () {
        return (
            <TopicWrapper>
                <TopicItem>
                    <img src={smallPic}/>
                    热点--
                </TopicItem>
            </TopicWrapper>
        )
    }
}

export default Topic;

然后再在,home 目录下的style.js 中 写入下面两个组件,如下。

export const TopicWrapper = styled.div`
    padding: 20px 0 10px 0;
    overflow: hidden;
    margin-left: -18px;
`;

export const TopicItem = styled.div`
    float: left;
    height: 32px;
    line-height: 32px;
    margin-left: 18px;
    margin-bottom: 18px;
    padding-right: 10px;
    font-size: 14px;
    background: #f7f7f7;
    color: #000;
    border: 1px solid #dcdcdc;
    border-radius: 4px;
    img {
        height: 32px;
        display: block;
        float: left;
        margin-right: 10px;
    }
`;

上面只写了一个TopicItem,但真实的话,会有很多Item。并且呢,它们都是从远程获取,循环显示出来。下面,我们实现这一部分。

我们在项目中,已经创建了store 和reducer。而且我们使用了 combineReducers 把小的reducer 合并到最终的reducer。那Topic 小组件是属于 home 的,因此我们在 src/pages/home 下创建目录 store 。然后在 store 下创建 reducer.js 我们在reducer.js 中管理 home 中的数据。

import { fromJS } from 'immutable';

const defaultState = fromJS({
    topicList: [{
        id: 1,
        title: '热点--',
        imgURL: '//upload.jianshu.io/users/upload_avatars/4802366/4f86b75d-b61b-4126-8be4-87a151c9cd28.jpg?imageMogr2/auto-orient/strip|imageView2/1/w/96/h/96/format/webp'
    }, {
        id: 2,
        title: '桃花--',
        imgURL: '//upload.jianshu.io/users/upload_avatars/3136195/484e32c3504a.jpg?imageMogr2/auto-orient/strip|imageView2/1/w/96/h/96/format/webp'
    }]
});

export default (state = defaultState, action) => {
    switch (action.type) {
        default:
            return state;
    }
}

然后,我们去src/store/reducer.js 中使用这个reducer。代码如下。

import { combineReducers } from 'redux-immutable';
import { reducer as headerReducer } from '../common/header/store';
import homeReducer from '../pages/home/store/reducer';

const reducer = combineReducers({
    header: headerReducer,
    home: homeReducer
});

export default reducer;

然后,就可以在Redux 控制台查看home 下的数据,如下。

当然,我们要稍微调整一下,把 store 下面的出口文件放在store 下的index.js 中。我们在 src/pages/home/store 下新建 index.js 文件,如下。

import reducer from './reducer';

export {reducer};

然后,在 src/store/reducer.js 中可以改成下面这样。

import { combineReducers } from 'redux-immutable';
import { reducer as headerReducer } from '../common/header/store';
import { reducer as homeReducer } from '../pages/home/store';

const reducer = combineReducers({
    header: headerReducer,
    home: homeReducer
});

export default reducer;

下面我们来将TopicItem 由homeReducer 中 topicList 循环渲染出来。

首先我们引入 react-redux 中的 connect 。 然后把这个组件和redux 连接上,如下。

import React, {Component} from 'react';
import { connect } from 'react-redux';
import { TopicWrapper, TopicItem } from '../style';

class Topic extends Component {
    render () {
        const { topicList } = this.props;
        return (
            <TopicWrapper>
                {topicList.map( (item) => {
                    return (
                    <TopicItem key={item.get("id")}>
                        <img src={item.get("imgURL")}/>
                        {item.get("title")}
                    </TopicItem>)
                })}
            </TopicWrapper>
        )
    }
}

const mapStateToProps = (state) => {
    return {
      topicList: state.get("home").get("topicList")
    }
  }


export default connect(mapStateToProps, null)(Topic);

Done.

猜你喜欢

转载自blog.csdn.net/purple_lumpy/article/details/89146663
2-3