9.2 使用redux管理详情页面
之前我们在detail/index.js里写了详情页面的内容,并且能够正常显示。但是,页面上的数据不应该写死,所以应该把页面上的数据放在store中进行管理,具体操作步骤如下:
一、在detail文件夹下创建store文件夹
二、在store文件夹下创建redux四件套
- 在store下创建actionCreaters.js,constants.js,reducer.js,index.js;
- 首先写reducer.js(可以从src下的store中的reducer里复制,粘贴到detail中的reducer里然后删去case,和逻辑代码留下框架);
//detail/store/reducer.js原型
import {fromJS} from 'immutable';
import * as constants from './constants';
export default (state = defaultState, action) => {
switch (action.type) {
default:
return state;
}
}
- 接下来写index.js(可以直接从src下的store中的index里复制,导入目录都正确的话甚至不用修改);
//detail/store/index.js
import reducer from './reducer';
import * as actionCreators from './actionCreaters';
import * as constants from './constants';
export { reducer, actionCreators, constants };
- 对于detail页面actionCreators和constants没有作用,不用写。
三、在reducer.js里写入数据(创建defaultState)
- 定义一个defaultState,创建初始数据:标题(title)、页面上的内容(content)
- 从已经写好的detail/index.js中剪切页面上要显示的内容
//detail/store/reducer.js原型
import {fromJS} from 'immutable';
import * as constants from './constants';
const defaultState = fromJS({
title: '岁月沧桑,从不荒凉',
content: '<h4>这世上最难走的路,叫生活,我们一路跌倒,一路坚强,任尘世流转,岁月沧桑,内心安然无恙。</h4><h4>三毛说:“人生如茶,第一道苦若生命,第二道甜似爱情,第三道淡如清风。” 其实,生命就是一个不断寻找,不断历练,不断感悟的过程,从最初的天真单纯,到百炼成钢,再到最后的云水禅心,是悟,亦是成长。</h4><img src="//upload-images.jianshu.io/upload_images/8733570-14afcb7ca90d1230.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/640/format/webp" /><h4>岁月沧桑,我依然坚强。坚强,是百折不挠的勇气,是跌倒之后的奋起,是世间最强大的力量,也是生命的希望。生活的酸甜苦辣,每个人都要品尝一遭,再苦再累,也要坚强,为自己,也为那些爱自己的人。</h4><h4>岁月沧桑,我依然善良。大千世界,芸芸众生,每个人都不尽相同,你不懂他的苦,他亦不懂你的痛,以一颗慈悲心相处,对身边的人和事,多些宽容。善良是一个人最伟大的情怀,是自我修养的提高,你的善良,万丈光芒。</h4>'
})
export default (state = defaultState, action) => {
switch (action.type) {
default:
return state;
}
}
四、修改主reducer.js
- 在src/store/reducer.js中引入刚刚写的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';
++import { reducer as detailReducer } from '../pages/detail/store'
const reducer = combineReducers({
header: headerReducer,
home: homeReducer,
++detail :detailReducer
});
export default reducer;
- 打开浏览器,用redux-devtools看到state中已经成功的存入刚刚写好的内容了。
在这里插入代码片
五、在页面中使用store中的内容
- 引入connect;
- 修改export;
- 定义mapState,从detail中拿title和content数据,注意这里要使用getIn方法而不是get方法。因为方括号内的内容是需要深度取的内容,故用getIn方法;
- 在render函数中引用数据,注意content不能直接写{this.props.content},
<Content>{ this.props.content }</Content>
因为里面的内容含有html标签,JSX中会被自动转义,为了不转义,要使用dangerouslySetInnerHTML;
<Content
dangerouslySetInnerHTML={{__html: this.props.content}}
/>
- 详情页面代码
//detail/index.js
import React, { Component } from 'react';
import { connect } from 'react-redux';//1.引入connect
import { DetailWrapper, Content, Header } from'./style';
class Detail extends Component {
render() {
return (
<DetailWrapper>
<Header>{this.props.title}</Header> //4.使用
<Content //4.使用
dangerouslySetInnerHTML={{__html: this.props.content}}
/>
</DetailWrapper>
)
}
}
//3.定义mapState
const mapState = (state) => ({
title: state.getIn(['detail', 'title']),
content: state.getIn(['detail', 'content'])
})
export default connect(mapState, null)(Detail); //2.修改export
六、小节
如下图所示,页面内容成功显示出来,到这为止,我们已经能够利用redux管理详情页面了。