React-redux应用
老样子,依旧从最简单的计数器开始学习。。。。
推荐直接用react脚手架进行操作
这是一个最简单的react-redux实现
- 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
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import ReactDOM from 'react-dom'
import { createStore } from 'redux'
import { Provider, connect } from 'react-redux'
// React component
class Counter extends Component {
render() {
const { value, onIncreaseClick } = this.props
return (
<div>
<span>{value}</span>
<button onClick={onIncreaseClick}>Increase</button>
</div>
)
}
}
Counter.propTypes = {
value: PropTypes.number.isRequired,
onIncreaseClick: PropTypes.func.isRequired
}
// Action
const increaseAction = { type: 'increase' }
// Reducer
function counter(state = { count: 0 }, action) {
const count = state.count
switch (action.type) {
case 'increase':
return { count: count + 1 }
default:
return state
}
}
// Store
const store = createStore(counter)
// Map Redux state to component props
function mapStateToProps(state) {
return {
value: state.count
}
}
// Map Redux actions to component props
function mapDispatchToProps(dispatch) {
return {
onIncreaseClick: () => dispatch(increaseAction)
}
}
// Connected Component
const App = connect(
mapStateToProps,
mapDispatchToProps
)(Counter)
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
)
介绍一下各部分功能
Store
const store = createStore(reducer)
创建一个综合状态管理的仓库
Reducer
通常在这里分发要进行的操作,根据当前state和指定action返回一个新的state,管理状态数据
action
这是包含n个用来创建action的工厂函数(action creator) 在这里写改变状态的函数
接下来我们把他们分成模块管理,再来写一个demo
推荐写法:
store.js
redux最核心的管理对象: store
- 1
- 2
- 3
- 4
- 5
import {createStore} from 'redux'
import reducer from './reducer'
export default createStore(reducer) // 创建store对象内部会第一次调用reducer()得到初始状态值
action-types.js 用来写常量
- 1
- 2
- 3
//包含n个action type常量名称的模块
export const INCREMENT = 'increment'
export const DECREMENT = 'decrement'
action.js
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
//包含n个用来创建action的工厂函数(action creator)
import {INCREMENT, DECREMENT} from './action-types'
//增加的action
export const increment = number => ({type: INCREMENT, data: number})
//减少的action
export const decrement = number => ({type: DECREMENT, data: number})
reducer.js
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
import {INCREMENT, DECREMENT} from './action-types'
//管理count状态数据的reducer
export default function count(state=1, action) {
console.log('count()', state, action)
switch (action.type) {
case INCREMENT:
return state + action.data
case DECREMENT:
return state - action.data
default:
return state
}
}
index.js 入口文件
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
//入口文件
import React from 'react'
import ReactDOM from 'react-dom'
import { Provider } from 'react-redux'
import App from './App'
import store from './redux/store'
ReactDOM.render((
<Provider store={store}>
<App />
</Provider>),
document.getElementById('root')
)
App.js count组件
- 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
import React, { Component } from 'react'
import { increment, decrement } from './redux/actions'
import { connect } from 'react-redux'
class Counter extends Component {
increment = () => {
this.props.increment(1)
}
decrement = () => {
this.props.decrement(1)
}
render() {
const count = this.props.count
return (
<div>
<p>count: {count} </p>
<button onClick={this.increment}>+</button>
<button onClick={this.decrement}>-</button>
</div>
)
}
}
// 指定向Counter传入哪些一般属性(属性值的来源就是store中的state)
const mapStateToProps = (state) => ({ count: state })
// 指定向Counter传入哪些函数属性
/*如果是函数, 会自动调用得到对象, 将对象中的方法作为函数属性传入UI组件*/
/*const mapDispatchToProps = (dispatch) => ({
increment: (number) => dispatch(increment(number)),
decrement: (number) => dispatch(decrement(number)),
})*/
/*如果是对象, 将对象中的方法包装成一个新函数, 并传入UI组件 */
const mapDispatchToProps = { increment, decrement }
export default connect(
mapStateToProps,
mapDispatchToProps
)(Counter)
接下来我们需要实现异步的,再来写一个demo,多用于网络请求
这里我们要用到的中间件
'redux-thunk'的thunk,
redux的applyMiddleware,
开发工具(可选,用于redux-devtools的调试) 'redux-devtools-extension'的composeWithDevTools
store.js
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
import {createStore, applyMiddleware} from 'redux'
import thunk from 'redux-thunk' // 用来实现redux异步的redux中间件插件
import {composeWithDevTools} from 'redux-devtools-extension'
import reducer from './reducer'
export default createStore(reducer, composeWithDevTools(applyMiddleware(thunk)))
//生产可以把composeWithDevTools()包装去除
action-types.js 用来写常量
- 1
- 2
- 3
//包含n个action type常量名称的模块
export const INCREMENT = 'increment'
export const DECREMENT = 'decrement'
action.js 这里我们用定时器添加一个异步的操作
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
//包含n个用来创建action的工厂函数(action creator)
import {INCREMENT, DECREMENT} from './action-types'
//增加的action
export const increment = number => ({type: INCREMENT, data: number})
//减少的action
export const decrement = number => ({type: DECREMENT, data: number})
//增加的异步action: 返回的是函数
export const incrementAsync = number => {
return dispatch => {
// 1. 执行异步(定时器, ajax请求, promise)
setTimeout(() => {
// 2. 当前异步任务执行完成时, 分发一个同步action
dispatch(increment(number))
}, 1000)
}
}
reducer.js
这里我们添加一个redux的combineReducers接收包含所有reducer函数的对象, 返回一个新的reducer函数(总reducer) 总的reducer函数管理的state的结构
- 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
import {INCREMENT, DECREMENT} from './action-types'
//管理count状态数据的reducer
function count(state=1, action) {
console.log('count()', state, action)
switch (action.type) {
case INCREMENT:
return state + action.data
case DECREMENT:
return state - action.data
default:
return state
}
}
function user(state = {admin:"admin"}, action) {
switch (action.type) {
default:
return state
}
}
export default combineReducers({
count,
user
})
index.js 入口文件
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
//入口文件
import React from 'react'
import ReactDOM from 'react-dom'
import { Provider } from 'react-redux'
import App from './App'
import store from './redux/store'
ReactDOM.render((
<Provider store={store}>
<App />
</Provider>),
document.getElementById('root')
)
App.js count组件
- 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
import React, { Component } from 'react'
import { increment, decrement,incrementAsync} from './redux/actions'
import { connect } from 'react-redux'
class Counter extends Component {
increment = () => {
this.props.increment(1)
}
decrement = () => {
this.props.decrement(1)
}
incrementAsync = () => {
this.props.incrementAsync(2)
}
render() {
const count = this.props.count
const user = this.props.user
console.log(user)
return (
<div>
<p>user: {user.name} </p>
<p>count: {count} </p>
<button onClick={this.increment}>+</button>
<button onClick={this.decrement}>-</button>
<button onClick={this.incrementAsync}>异步+2</button>
</div>
)
}
}
//注意此处写法
const mapStateToProps = (state) => ({ count: state.count ,user: state.user })
const mapDispatchToProps = { increment, decrement,incrementAsync}
export default connect(
mapStateToProps,
mapDispatchToProps
)(Counter)
(完)
0条看法
最新最后最热
等待你的评论