在前面的文章《到底什么是Redux中间件——基于Redux-thunk和Redux-saga理解分析》中,我们已经介绍过redux中间件Redux-thunk
和Redux-saga
的基本使用了。本篇文章,我们介绍一个基于Redux-chunk
的新的中间件react-redux
,这个中间件也是我在平常工作中使用最多的中间件。
一、项目源码展示
在本篇文章中,我们会以简单的TodoList的实现来讲解react-redux的使用。下面是我们已经搭建好的初始项目目录。我们需要注意用红色框标注出来的三段块代码。为了增强文章的可读性,我也将源码一并贴出。
/src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import TodoList from './TodoList'
ReactDOM.render(
<React.StrictMode>
<TodoList />
</React.StrictMode>,
document.getElementById('root')
);
/src/TodoList.js
import React, { Component } from 'react'
import store from './store'
class TodoList extends Component{
constructor(props){
super(props)
this.state = store.getState()
}
render(){
return (
<div>
<div>
<input value={this.state.inputValue}/>
<button>提交</button>
</div>
<ul>
{
this.state.list.map((item,index) => {
return (<li key={index}>{item}</li>)
})
}
</ul>
</div>
)
}
}
export default TodoList
/src/store/index.js
import { createStore } from 'redux'
import reducer from './reducer'
const store = createStore(reducer)
export default store
/src/store/reducer.js
const defaultState = {
inputValue: '',
list: []
}
export default (state = defaultState, action) => {
if(action.type === 'change_input_value'){
console.log('ddd')
const newState = JSON.parse(JSON.stringify(state))
newState.inputValue = action.value
return newState
}
return state
}
上面就是项目的初始源代码,主要是Store
的简单应用,下面我们就要使用react-redux
优化和修改这写代码。
二、react-redux中的基本概念
使用react-redux,我们需要掌握几个基本的概念,依次是Provider、connect、mapStateProps、mapdispatchToProps
。他们的所代表的含义见下表。
方法 | 含义 |
---|---|
Provider | 提供器,接受store,被<Provider>组件包裹的组件都能使用store中传递过来的数据 |
connect | 将组件(被<Provider>包裹起来的组件)和store链接起来 |
mapStateToProps | 将store中的数据通过props映射到组件(被<Provider>包裹起来的组件)中 |
mapdispatchToProps | 组件(被<Provider>包裹起来的组件)需要改变store中的数据时,将操作方法放在此方法中 |
可能你对这几个概念还比较陌生,没关系,看完了下面的具体流程,相信你会对react-redux
有一个全面的认识。
三、react-redux的使用流程
1、安装react-redux
yarn add react-redux
2、引入提供器(Provider),并绑定store数据,并划定数据相应的范围
/src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import TodoList from './TodoList'
+import store from './store'
+import { Provider } from 'react-redux'
+const App = (
+ <Provider store={store}>
+ <TodoList />
+ </Provider>
+)
ReactDOM.render(
+ App,
document.getElementById('root')
);
引入Provider,绑定store。通过此处设置,<Provider>组件中的所有组件都能能拿到store中的数据。
3、将组件和Store关联起来并设置数据操作的方法
/src/TodoList.js
1、引入connect,配置相关connect
import { connect } from 'react-redux'
...
export default connect(mapStateToProps, mapDispatchToProps)(TodoList)
2、实现数据操作的相关逻辑
const mapStateToProps = (state) => {
return {
inputValue: state.inputValue,
list: state.list
}
}
const mapDispatchToProps = (dispatch) => {
return {
changeInputValue(e){
const action = {
type: 'change_input_value',
value: e.target.value
}
dispatch(action)
}
}
}
3、使用数据
class TodoList extends Component{
render(){
+ const { inputValue, list, changeInputValue } = this.props
return (
<div>
<div>
+ <input value={inputValue} onChange={changeInputValue}/>
<button>提交</button>
</div>
<ul>
{
+ list.map((item,index) => {
+ return (<li key={index}>{item}</li>)
+ })
}
</ul>
</div>
)
}
}
下面是TodoList.js完整的代码:
import React, { Component } from 'react'
import { connect } from 'react-redux'
class TodoList extends Component{
render(){
const { inputValue, list, changeInputValue, handleAddItem, handleDeleteItem } = this.props
return (
<div>
<div>
<input value={inputValue} onChange={changeInputValue}/>
<button onClick={handleAddItem}>提交</button>
</div>
<ul>
{
list.map((item,index) => {
return (<li onClick={handleDeleteItem.bind(this, index)} key={index}>{item}</li>)
})
}
</ul>
</div>
)
}
}
const mapStateToProps = (state) => {
return {
inputValue: state.inputValue,
list: state.list
}
}
const mapDispatchToProps = (dispatch) => {
return {
changeInputValue(e){
const action = {
type: 'change_input_value',
value: e.target.value
}
dispatch(action)
},
handleAddItem(){
const action = {
type: 'handle_add_item'
}
dispatch(action)
},
handleDeleteItem(index){
const action = {
type: 'handle_delete_item',
}
dispatch(action)
}
}
}
export default connect(mapStateToProps, mapDispatchToProps)(TodoList)
当然,这个组件是只有一个render钩子函数,也就是我们所说的``无状态组件```,无状态组件可以很好提升性能,主要原因有两点
1、没有任何生命周期函数,代码执行流畅度高
2、不会生成真正的组件实例,提升了性能
修改为无状态组件的代码如下:
import React from 'react'
import { connect } from 'react-redux'
const TodoList = (props) => {
const { inputValue, list, changeInputValue, handleAddItem, handleDeleteItem } = props
return (
<div>
<div>
<input value={inputValue} onChange={changeInputValue}/>
<button onClick={handleAddItem}>提交</button>
</div>
<ul>
{
list.map((item,index) => {
return (<li onClick={handleDeleteItem.bind(this, index)} key={index}>{item}</li>)
})
}
</ul>
</div>
)
}
const mapStateToProps = (state) => {
return {
inputValue: state.inputValue,
list: state.list
}
}
const mapDispatchToProps = (dispatch) => {
return {
changeInputValue(e){
const action = {
type: 'change_input_value',
value: e.target.value
}
dispatch(action)
},
handleAddItem(){
const action = {
type: 'handle_add_item'
}
dispatch(action)
},
handleDeleteItem(index){
const action = {
type: 'handle_delete_item',
}
dispatch(action)
}
}
}
export default connect(mapStateToProps, mapDispatchToProps)(TodoList)
至此,react-redux的基本使用已经介绍完了。感谢你的阅读。
网友评论