文章目录
  1. 1. Top组件
    1. 1.1. Top组件功能
    2. 1.2. 添加action
    3. 1.3. 添加reducer
    4. 1.4. 添加Top组件
    5. 1.5. HomeContainer传入状态
  2. 2. 会话状态
    1. 2.1. 使用sessionStorage保存登录信息
  3. 3. 结束语

最近又重新拾起了React框架,并配合开源模板gentelella以及Redux建立了个简单的项目。《React-Redux使用笔记》系列用于记录过程中的一些使用和解决方法。
本文记录创建Top组件的过程。

Top组件


上一节我们引入了Redux,项目结构进行了大调整,可能小伙伴们会觉得一脸迷糊。这里我们通过添加个小的Top组件再来细讲一下Redux在React中的使用吧。

Top组件功能

  • 收起左侧列表

    我们将添加一个状态isSidebarShown,来记录左侧列表的状态。

  • 退出登录

    我们将重置状态userName,并退出应用。

添加action

这里我们先添加isSidebarShown状态相关的action和action创建函数:

1
2
3
4
5
// actions/commonActions.js
export const TOGGLE_SIDEBAR = 'TOGGLE_SIDEBAR'
export function toggleSidebar(state) {
return { type: TOGGLE_SIDEBAR, state }
}

添加reducer

然后我们添加isSidebarShown状态相关的reducer:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// store/reducers.js
import { USER_NAME, TOGGLE_SIDEBAR } from '../actions/commonActions'
// 默认值为true
function isSidebarShown(state = true, action) {
switch (action.type) {
case TOGGLE_SIDEBAR:
return action.state
default:
return state
}
}
// 合并多个reducers
const AppReducer = combineReducers({
isSidebarShown,
userName
})

添加Top组件

我们约定,页面结构相关的组件放置在components文件中,路由相关的组件放置在modules中。
这里我们在routes/home/components文件夹下新增Top.jsx组件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
// Top.jsx
import React, { Component, PropTypes } from 'react'
import { toggleSidebar, setUserName } from '../../../actions/commonActions.js'
export class Top extends Component {
render() {
// 我们将会从父组件中传入dispatch和isSidebarShown
const { dispatch, isSidebarShown } = this.props
return (
<div className="top_nav">
<div className="nav_menu">
<nav>
<div className="nav toggle">
<a id="menu_toggle" onClick={() => { dispatch(toggleSidebar(isSidebarShown() ? false : true)); $('body').toggleClass('nav-md nav-sm') } }><i className="fa fa-bars"></i></a>
</div>
<ul className="nav navbar-nav navbar-right">
<li className="">
<a href="javascript:;" className="user-profile dropdown-toggle" data-toggle="dropdown" aria-expanded="false">
用户
<span className=" fa fa-angle-down"></span>
</a>
<ul className="dropdown-menu dropdown-usermenu pull-right">
<li><a href="javascript:;">设置</a></li>
<li><a onClick={() =>{this.logout()}}><i className="fa fa-sign-out pull-right"></i>退出</a></li>
</ul>
</li>
</ul>
</nav>
</div>
</div>
)
}
logout(){
// 将用户名设置为null,并退出页面
this.props.dispatch(setUserName(null))
this.context.router.push('/login')
}
}
Top.contextTypes = {
router: React.PropTypes.object
}
export default Top

HomeContainer传入状态

这里相关状态我们统一从HomeContainer组件中传入:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
// HomeContainer.jsx
import React, { Component, PropTypes } from 'react'
import { connect } from 'react-redux'
import Top from '../components/Top.jsx'
export class HomeContainer extends Component {
render() {
const that = this
const { dispatch, isSidebarShown } = that.props
return (
<div className="container body">
<div className="main_container">
<Top dispatch={dispatch} isSidebarShown={isSidebarShown}></Top>
<div className="right_col" role="main">
Hello World!
</div>
<footer>
<div className="pull-right">
@godbasin
</div>
<div className="clearfix"></div>
</footer>
</div>
</div>
)
}
componentDidMount() {
// 判断如果未登陆则跳转
if (this.props.getUserName() === null) {
Notify({
title: '请先登录',
type: 'error'
})
this.context.router.push('/login')
}
$('body').attr('class', 'nav-md')
$('.right_col').css('min-height', $(window).height())
}
}
HomeContainer.contextTypes = {
router: React.PropTypes.object
}
function connectState(state) {
return {
getUserName() {
return state.userName
},
isSidebarShown() {
return state.isSidebarShown
}
}
}
// 使用connect,注入dispatch和userName/isSidebarShown
export default connect(connectState)(HomeContainer)

至此,我们的Top组件就可以使用啦。

会话状态


前面为了展示redux的使用,我们将登录信息也做到状态里面,但其实这样是很不合理的,因为我们刷新一下页面就会退出了呢。

使用sessionStorage保存登录信息

sessionStorage也是本骚年用的最经常的一种保存会话信息的方法。

我们需要调整的代码如下:

  • action
1
2
3
4
5
6
// commonActions.js
// 移除相关action
// export const USER_NAME = 'USER_NAME'
// export function setUserName(state) {
// return { type: USER_NAME, state }
// }
  • reducer
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// reducers.js
// 移除相关reducer
// import { USER_NAME, TOGGLE_SIDEBAR } from '../actions/commonActions'
import { TOGGLE_SIDEBAR } from '../actions/commonActions'
// function userName(state = null, action) {
// switch (action.type) {
// case USER_NAME:
// return action.state
// default:
// return state
// }
// }
// const AppReducer = combineReducers({
// isSidebarShown,
// userName
// })
// 合并多个reducers
const AppReducer = combineReducers({
isSidebarShown
})
  • Login组件
1
2
3
4
5
6
7
8
9
10
// Login.jsx
// 移除dispatch以及相关connect
// import { connect } from 'react-redux'
// import { setUserName } from '../../actions/commonActions.js'
// this.props.dispatch(setUserName(username))
sessionStorage.setItem('username', username)
// export default connect()(Login)
export default Login
  • HomeContainer组件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// HomeContainer.jsx
function connectState(state) {
return {
/*getUserName() {
return state.userName
},*/
isSidebarShown() {
return state.isSidebarShown
}
}
}
// if (this.props.getUserName() === null){ ... }
if (!sessionStorage.getItem('username')){ ... }
  • Top组件
1
2
3
// Top.jsx
// this.props.dispatch(setUserName(null))
sessionStorage.removeItem('username')

调整后的功能终于符合逻辑了呢,现在我们的页面大概效果如图:
image
切换后:
image

结束语


本节我们通过新增一个Top组件,感受了一下在Redux状态管理下,新加状态的一些具体步骤,这样或许比上一节整体调整结构要稍微清晰一点点吧。
此处查看项目代码
此处查看页面效果

查看Github有更多内容噢:https://github.com/godbasin
更欢迎来被删的前端游乐场边撸猫边学前端噢

码生艰难,写文不易,给我家猪囤点猫粮了喵~

作者:被删

出处:https://godbasin.github.io

本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

文章目录
  1. 1. Top组件
    1. 1.1. Top组件功能
    2. 1.2. 添加action
    3. 1.3. 添加reducer
    4. 1.4. 添加Top组件
    5. 1.5. HomeContainer传入状态
  2. 2. 会话状态
    1. 2.1. 使用sessionStorage保存登录信息
  3. 3. 结束语