文章目录
- 1、优化项目结构
- 2、添加一个新容器组件
- 2.1、新项目结构
- 2.2、CODE
- 2.2.1、reduc/constant.js
- 2.2.2、redux/actions/person.js
- 2.2.3、redux/reducers/person.js
- 2.2.4、redux/store.js
- 2.2.5、Count.jsx
- 2.2.6、Person.jsx
- 2.3、Result
- 3、总结
本示例修改自 上一章 求和Demo
1、优化项目结构
- 将redux下的action和reducer单独分类方便管理,因为现在要写第二个第三个第n个容器组件了
2、添加一个新容器组件
2.1、新项目结构
2.2、CODE
2.2.1、reduc/constant.js
/**
* action.type常量
*/
// for Count
export const INCREMENT = 'increment'
export const DECREMENT = 'decrement'
// for Person
export const ADD_PERSON = 'add_person'
2.2.2、redux/actions/person.js
import { ADD_PERSON } from '../constant'
// 创建添加一个人信息的动作对象
export const createAddPersonAction = data => ({ type: ADD_PERSON, data })
2.2.3、redux/reducers/person.js
import { ADD_PERSON } from '../constant'
export default function personReducer(preState = [], action) {
const { type, data } = action
switch (type) {
case ADD_PERSON:
return [data, ...preState]
default:
return preState
}
}
2.2.4、redux/store.js
import {
// 引入createStore,专门用于创建redux中最为核心的store对象
createStore,
// 引入applyMiddleware 执行中间件
applyMiddleware,
// 引入 combineReducers 组合 reducers
combineReducers
} from 'redux'
//引入reducers
import countReducer from './reducers/count'
import personReducer from './reducers/person'
// 引入 redux-thunk 用于支持异步action
import thunk from 'redux-thunk'
// 共享就得把 reducer 组合到一起传进去
const allReducers = combineReducers({
count: countReducer,
people: personReducer
})
//暴露store
export default createStore(allReducers, applyMiddleware(thunk))
2.2.5、Count.jsx
// import 未改变,略...
class Count extends Component {
// 方法等都未改变,略...
render() {
const { count, people } = this.props
return (
<div>
<h2>我是Count,下面已经添加了{people.length}个人</h2>
{/* 内容全部未变,略... */}
</div >
)
}
}
// 暴露容器组件
export default connect(
state => ({
count: state.count,
people: state.people
}),
{
// 未改变,略...
}
)(Count)
2.2.6、Person.jsx
import React, { Component } from 'react'
import { connect } from 'react-redux'
import { nanoid } from 'nanoid'
import { createAddPersonAction } from '../../redux/actions/person'
class Person extends Component {
state = {
name: '',
age: '',
}
submit = () => {
this.props.add({
id: nanoid(),
...this.state
})
// 清空表单
this.setState({
name: '',
age: ''
})
}
render() {
const { name, age } = this.state
const { people, count } = this.props
return (
<div>
<h2>我是Person,上面求和为{count}</h2>
<input
type='text'
name="name"
placeholder='请输入名字'
value={name}
onChange={e => this.setState({ name: e.target.value })}
/><br />
<input
type='text'
name="age"
placeholder='请输入年龄'
value={age}
onChange={e => this.setState({ age: e.target.value })}
/><br />
<button onClick={this.submit}>添加</button><br />
<ul>
{
people.map(i => (
<li key={i.id}>
{`姓名:${i.name}-年龄:${i.age}`}
</li>
))
}
</ul>
</div >
)
}
}
export default connect(
state => ({
people: state.people,
count: state.count
}),
{
add: createAddPersonAction
}
)(Person)
2.3、Result
3、总结
- 定义一个Pserson组件,和Count组件通过redux共享数据
- 为Person组件编写:reducer、action,配置constant常量
- 重点:Person的reducer和Count的Reducer要使用combineReducers进行合并,合并后的总状态是一个对象!!!
- 交给store的是总reducer,最后注意在组件中取出状态的时候,记得“取到位”
*补充:纯函数
- 一类特别的函数: 只要是同样的输入(实参),必定得到同样的输出(返回)
- 必须遵守以下一些约束
- 不得改写参数数据
- 不会产生任何副作用,例如网络请求,输入和输出设备
- 不能调用Date.now()或者Math.random()等不纯的方法
redux的reducer函数必须是一个纯函数