在使用redux之前先了解下两个概念,UI组件和容器组件。
UI组件:不能使用任何redux的api,只负责页面的呈现,交互等
容器组件:负责和redux通信,将结果交给UI组件
先看一下demo文件结构
第一步: UI组件触发action文件 (src/containers/Count/index.js )
// npm install react-redux
import React, { Component } from 'react'
// 引入connect用于连接UI组件与redux
import { connect } from 'react-redux'
import {
increment111,
decrement111,
incrementAsync111
}
from '../../redux/actions/count'
// 定义UI组件Count
class Count extends Component {
state = { carName: 'BMW' }
increment = () => {
const { value } = this.selectNumber
this.props.jia(value * 1)
}
decrement = () => {
const { value } = this.selectNumber
this.props.jian(value * 1)
}
incrementOIfOdd = () => {
const { value } = this.selectNumber
if (this.props.n % 2 !== 0) {
this.props.jia(value * 1)
}
}
incrementAsync = () => {
const { value } = this.selectNumber
this.props.asyncJia(value * 1, 500)
}
render() {
console.log('UI组件接收到的props是', this.props)
return (
<div>
<h2>Count组件</h2>
<h4>当前求和为: {this.props.n},下方组件总人数为{this.props.renshu} </h4>
<select ref={c => this.selectNumber = c} name="" id="">
<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.incrementOIfOdd}>当前求和为奇数再加</button>
<button onClick={this.incrementAsync}>异步加</button>
</div>
)
}
}
// 使用connect()()创建并暴露一个Count的容器组件
const CountContainer = connect(
state1 => ({ n: state1.he, renshu: state1.ren.length }),
{
jia: increment111,
jian: decrement111,
asyncJia: incrementAsync111
}
)(Count)
export default CountContainer
第二步:容器组件收到了Count UI组件的触发信息,并生成自己的action对象。(src/redux/actions/count.jsCount)
/**
* 该文件专门为Count组件生成action对象
*/
import { INCREMENT, DECREMENT } from '../constant'
import store from '../store'
// 同步action,就是指action的值为Object类型的一般对象
export function increment111(data) {
// return { type: 'increment', data: data }
return { type: INCREMENT, data }
}
export function decrement111(data) {
// return { type: 'decrement', data: data }
return { type: DECREMENT, data }
}
// 同步action,就是指action的值为函数,异步action中一般都会调用同步action,异步action不是必须要用的
export function incrementAsync111(data, time) {
return () => {
setTimeout(() => {
store.dispatch({ type: INCREMENT, data: data })
}, time)
}
}
第三步:暴露store对象(src/redux/store.js)
/**
* 该文件专门用于暴露一个store对象,整个应用只有一个store对象
*/
// 引入createStore,专门用于创建redux中最为核心的store对象,
// applyMiddleware是中间件
import { createStore, applyMiddleware } from 'redux'
// 引入汇总之后的reducer
import allRecuders from './reducers'
// 引入redux-thunk,用于支持异步action
import thunk from 'redux-thunk'
// 引入redux-devtools-extension
import { composeWithDevTools } from 'redux-devtools-extension'
// 仅仅只使用一个store
// const store = createStore(countReducer, applyMiddleware(thunk))
// export default store
const store = createStore(allRecuders, composeWithDevTools(applyMiddleware(thunk)))
export default store
第四步:引入总的reducers文件(src/redux/reducers/index.js)
// 该文件用于汇总所有的reducer为一个总的reducer
// combineReducers使用多个reducer count和person
import { combineReducers } from 'redux'
// 引入为Count组件服务的reducer
import countReducer from './count'
// 引入为Person组件服务的reducer
import personReducer from './person'
// 汇总所有的reducer变为一个总的reducer
export default combineReducers({
he: countReducer,
ren: personReducer
})
第五步:引入分的reducer文件(src/redux/reducers/count.js)
/**
* 1.该文件是用于创建一个为Count组件服务的reducer,reducer的本质是一个函数
* 2.reducer函数会接到两个参数,分别为:之前的状态(preState),动作对象(action)
* 3.reducer就是初始化状态和加工状态的
*/
import { INCREMENT, DECREMENT } from '../constant'
const initState = 0 // 初始化状态
export default function countReducer(preState = initState, action) {
// console.log(preState, action);
// 从action对象中获取: type,data
const { type, data } = action
// 根据type决定如何加工数据
switch (type) {
case INCREMENT: // 如果是加
return preState + data
case DECREMENT: // 如果是减
return preState - data
default:
return preState
}
}
其中,src/redux/constant.js文件是用于定义action对象中type类型的常量值
/**
* 该模块是用于定义action对象中type类型的常量值
* 目的:防止单词写错
*/
export const INCREMENT = 'increment'
export const DECREMENT = 'decrement'
export const ADD_PERSDON = 'add_person'
demo 截图