目录
1.redux要点
connect是连接React组件与Redux store,建立组件与store.state和dispatch的映射关系。
连接操作不会改变原来的组件类。返回一个新的已于Redux store连接的组件类
combineReducers 辅助函数的作用是,把一个由多个不同 reducer 函数作为 value 的 object,合并成一个最终的 reducer 函数,然后就可以对这个 reducer 调用 createStore
2.项目结构
3.源码效果
reducers.js
/* 包含n个reducer函数的模块 */
import {combineReducers} from 'redux'
import {INCREMENT, DECREMENT} from './action-types'
//指定形参默认值
export function counter(state = 0, action) {
console.log('counter', state, action)
switch (action.type) {
case INCREMENT:
return state + action.data
case DECREMENT:
return state - action.data
default:
return state
}
}
//默认返回counter
export default combineReducers({
counter
})
store.js
import React from 'react'
import {createStore, applyMiddleware} from 'redux'
import thunk from 'redux-thunk'
import {composeWithDevTools} from 'redux-devtools-extension'
import reducers from './reducers'
// 根据counter函数创建store对象
export default createStore(
reducers,
composeWithDevTools(applyMiddleware(thunk)) // 应用上异步中间件
)
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './containers/app';
//react-redux自动提供store.subscribe(render)
import {Provider} from 'react-redux'
import store from './redux/store'
ReactDOM.render((
<Provider store={store}>
<App />
</Provider>
),document.getElementById('root'))
app.jsx
import React from 'react'
// 引入连接函数
import {connect} from 'react-redux'
// 引入action函数
import {increment, decrement, incrementAsync} from '../redux/actions'
import Counter from '../components/counter'
// 连接React组件与Redux store
// 建立组件与store.state和dispatch的映射关系
// 连接操作不会改变原来的组件类。返回一个新的已于Redux store连接的组件类。
export default connect(
state => ({count: state.counter}),
{increment, decrement, incrementAsync}
)(Counter)
actions.js
/*
action creator模块
同步的action返回的是一个对象
异步的action返回的是一个函数
*/
import {INCREMENT, DECREMENT} from './action-types'
export const increment = (number) => ({type: INCREMENT,data: number})
export const decrement = (number) => ({type: DECREMENT,data: number})
// 异步action creator(返回一个函数)
export const incrementAsync = (number) => {
return dispatch => {
//异步代码
setTimeout(() => {
//1s之后分发一个增加的action
dispatch(increment(number))
}, 1000)
}
}
counter.jsx
import React, {Component} from 'react'
import PropTypes from 'prop-types'
export default class Count extends Component {
static propTypes = {
count: PropTypes.number.isRequired,
increment: PropTypes.func.isRequired,
decrement: PropTypes.func.isRequired
}
increment = () =>{
//1.得到选择,增加数量
const number = this.select.value*1
//2.调用store的方法更新状态
// this.props.store.dispatch({type:INCREMENT,data:number})
this.props.increment(number)
}
decrement = () =>{
//1.得到选择,增加数量
const number = this.select.value*1
//2.调用store的方法更新状态
// this.props.store.dispatch({type:DECREMENT,data:number})
this.props.decrement(number)
}
incrementIfOdd = () =>{
//1.得到选择,增加数量
const number = this.select.value*1
//2.得到原本count状态,并计算新count
const count = this.props.count
//判断满足条件再更新
if(count%2===1){
//3.更新状态
// this.props.store.dispatch({type:INCREMENT,data:number})
this.props.increment(number)
}
}
incrementAsync = () =>{
//1.得到选择,增加数量
const number = this.select.value*1
//2.得到原本count状态,并计算新count
//启动延时定时器
setTimeout(() => {
//3.更新状态
this.props.incrementAsync(number)
},1000)
}
render() {
//从外层获取参数
//传结构用const {count},传数值用户= count
const {count} = this.props
// debugger
return (
<div>
<p>click {count} times</p>
<div>
<select ref={select => this.select =select}>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<button onClick={this.increment}>+</button>
<button onClick={this.decrement}>-</button>
<button onClick={this.incrementIfOdd}>increment if odd</button>
<button onClick={this.incrementAsync}>increment async</button>
</div>
</div>
)
}
}
actions-types.js
同上一节