1、案例说明
使用 react + redux + react-redux
实现 TodoLit
案例。
2、实现步骤
2.1、安装依赖
cnpm i redux react-redux --save
2.2、封装底层代码
项目目录结构
- src
- store 管理状态的目录
- index.js 用于生成 store 对象
- reducer.js 用于生成 reducer 函数
- state.js 用于生成初始化 state 对象
- map.js 用于创建 store 与 props 的映射函数,props指组件中的props对象
- word.js 用于生成数据字典常量
- Input 输入框组件
- index.jsx
- index.css
- List 列表组件
- index.jsx
- index.css
- App.jsx 根组件
- index.js 入口文件
2.2.1、创建 store
创建 store/reducer.js
const reducer = (state,action) => {
return state
}
export default reducer
创建 store/state.js
const state = {
value: '',
list: []
}
export default state
创建 store/index.js
import {createStore} from 'redux'
import reducer from './reducer'
import state from './state'
const store = createStore(reducer,state)
export default store
2.2.2、创建映射文件
创建 store
与组件中的 props
之间的映射文件。
创建 store/map.js
//store中的state与组件中props的映射
const mapState = state => {
return {
value: state.value,
list: state.list
}
}
//store中的dispatch与组件中props的映射
const mapDispatch = dispatch => {
return {
}
}
export {
mapState,
mapDispatch
}
2.3、实现功能
2.3.1、输入功能
更新 store/reducer.js
代码:
const reducer = (state,action) => {
//更新value的值
if(action.type === 'change_value'){
let temp = JSON.parse(JSON.stringify(state))
temp.value = action.value
return temp
}
return state
}
export default reducer
更新 store/map.js
代码:
//只需要更新mapDispatch函数即可
//store中的dispatch与组件中props的映射
const mapDispatch = dispatch => {
//此处返回的的组件中的props上的函数
return {
changeValue(value){ //更新value数据的函数
dispatch({
type: 'change_value',
value
})
}
}
}
创建 Input/index.jsx
组件:
import React,{Component} from 'react'
import {connect} from 'react-redux'
import {mapState,mapDispatch} from '../store/map'
class index extends Component {
//更新value
change(e){
this.props.changeValue(e.target.value)
}
render() {
return (
<div>
<input value={this.props.value} onChange={this.change.bind(this)} />
<div>{this.props.value}</div>
</div>
)
}
}
//当前组件是交给connect管理,在当前组件中就可以使用映射的props对象
export default connect(mapState,mapDispatch)(index)
2.3.2、添加数据
更新 store/reducer.js
代码:
const reducer = (state,action) => {
//更新value的值
if(action.type === 'change_value'){
let temp = JSON.parse(JSON.stringify(state))
temp.value = action.value
return temp
}
//添加数据
if(action.type === 'list_add'){
let temp = JSON.parse(JSON.stringify(state))
temp.list.push(temp.value)
temp.value = ''
return temp
}
return state
}
export default reducer
更新 store/map.js
代码:
//只需要更新mapDispatch函数即可
//store中的dispatch与组件中props的映射
const mapDispatch = dispatch => {
//此处返回的的组件中的props上的函数
return {
changeValue(value){ //更新value数据的函数
dispatch({
type: 'change_value',
value
})
},
listAdd(){ //添加数据
dispatch({
type: 'list_add'
})
}
}
}
更新 Input/index.jsx
组件:
import React,{Component} from 'react'
import {connect} from 'react-redux'
import {mapState,mapDispatch} from '../store/map'
class index extends Component {
//更新value
change(e){
this.props.changeValue(e.target.value)
}
//添加数据
submit(e){
//判断回车事件
if(e.target.charCode === 13){
this.props.listAdd()
}
}
render() {
return (
<div>
<input value={this.props.value}
onChange={this.change.bind(this)}
onKeyPress={this.submit.bind(this)}/>
<div>{this.props.value}</div>
</div>
)
}
}
//当前组件是交给connect管理,在当前组件中就可以使用映射的props对象
export default connect(mapState,mapDispatch)(index)
注意:
其他功能的实现过程与添加数据功能类似,使用“自底向上”的流程开发:
reducer --> map --> 自定义组件
2.3.3、引入组件
在 App.jsx
根组件中导入 Input
组件:
import Input from './Input/index.jsx'
function App() {
return (
<div>
<Input></Input>
</div>
)
}
export default App
在 index.js
入口文件中导入 react-redux
中的 Provider
组件来统一管理 store
对象:
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import {Provider} from 'react-redux'
import store from './store'
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>
,document.getElementById('root'));