react-redux
前言
在《每天学点React ~ react-redux》中,学习了react-redux的基本使用,但仅演示了一种组件而已,而在日常工作中,我们所需的组件肯定不止一个,会涉及相当多的组件,利用react-redux进行交互,那么本篇就来演示下多组件的场景下,如何利用react-redux进行交互吧。
前置准备
在上一个案例的基础上,我们新增多一个Person组件,将其添加在Count组件的下方,其内容是:
- 一个名字输入框
- 一个年龄输入框
- 一个添加按钮
- 一个列表展示已添加的信息
如下图所示
参考代码
import React, { Component } from 'react'
export default class Person extends Component {
addPerson = () => {
const nameNode = this.nameNode.value
const ageNode = this.ageNode.value
console.log(nameNode, ageNode)
}
render() {
return (
<div>
<h2>PerSon组件</h2>
<input ref={c => this.nameNode = c} type='text' placeholder='输入名字' />
<input ref={c => this.ageNode = c} type='text' placeholder='输入年龄' />
<button onClick={this.addPerson}>添加</button>
<ul>
<li>姓名1--年龄1</li>
<li>姓名2--年龄2</li>
<li>姓名3--年龄3</li>
</ul>
</div>
)
}
}
开始编码
- 定义常量
export const ADD_PERSON = 'add_person'
- 定义
action
import { ADD_PERSON } from "../constant"
// 创建添加Person对象的Action
export const createAddPersonAction = data => ({ type: ADD_PERSON, data })
- 定义
reducer
import { ADD_PERSON } from "../constant"
const initState = [{ name: '姓名', age: '年龄' }]
export default function personReducer(preState = initState, action) {
const { type, data } = action
switch (type) {
case ADD_PERSON:
return [data, ...preState]
default:
return preState
}
}
App组件引入Person组件
import React, { Component } from 'react'
import Count from './containers/Count'
import Person from './containers/Person'
export default class App extends Component {
render() {
return (
<div>
<Count/>
<hr/>
<Person/>
</div>
)
}
}
到了这里,是不是有小伙伴觉得就已经完成了呢?就跟Count组件一样可以运行了。
别急,我们在personReducer打印下看看有没有被初始化先。
export default function personReducer(preState = initState, action) {
console.log('personReducer')
const { type, data } = action
switch (type) {
case ADD_PERSON:
return [...preState, data]
default:
return preState
}
}
可以看到只有countReducer初始化了,personReducer没生效。仔细想一想,是不是还漏了什么没有定义呢?
在store.js中,我们之前引入过countReducer的,但是新添加的组件并没有引入
所以redux并没有帮我们管理起来,我们还需要在该文件中引入personReducer交由其进行管理才行。这里需要注意的是,当有多个reducer需要交给redux管理的时候,我们需要引入combineReducers函数,由它来帮我们保存所有状态。
// 引入 createStore,用于创建store对象
import { legacy_createStore as createStore, applyMiddleware, combineReducers} from 'redux'
// 引入为count组件服务的reducer
import countReducer from './reducers/count'
// 引入为person组件服务的reducer
import personReducer from './reducers/person'
// 引入 thunk 中间件
import thunk from 'redux-thunk'
// 暴露store,combineReducers传入的对象就是redux帮我们保存的那个总状态对象
export default createStore(combineReducers({
counts: countReducer,
persons: personReducer
}), applyMiddleware(thunk))
既然reducer都交给combineReducers管理了,那么我们前面的使用connect创建组件的方式自然也需要做一定的改变了,需要获取到state中,我们刚刚定义的键对象才行。
// count
export default connect(
state => ({ count: state.counts }),
{
increment: createIncrementAction,
decrement: createDecrementAction,
asyncIncrement: createIncrementAsyncAction,
}
)(Count)
// person
export default connect(
state => ({ person: state.persons }),
// state => ({ person: state }),
{ addPerson: createAddPersonAction }
)(Person)
两个组件都正常初始化成功了。再来测试一下功能是否都能正常使用。
组件互通
到了这里,两个组件各自都能正常使用了,但是我们需要做的是组件之间也可以进行交互,那么应该如何做呢?
小伙伴们想一下,既然我们已经把reducer交由redux帮我们管理了,我们在使用connect定义的时候也是从props中拿到的状态,既然能拿到自己的,为什么不能拿到别的组件的呢?说做就做,尝试一下看看,在state中同时获取另一个组件状态
export default connect(
state => ({ person: state.persons, count: state.counts }),
{ addPerson: createAddPersonAction }
)(Person)
可以看到是能正常获取到别的组件的,这样我们就可以实现组件间的交互了。
本文正在参加「金石计划 . 瓜分6万现金大奖」