理解:react-Redux将所有组件分成两大类
· UI组件
1)只负责UI的呈现,不带有任何的业务逻辑
2)通过props接收数据(一般数据和函数)
3)不使用任何Redux的API
·容器组件
1)负责管理数据和业务逻辑,不负责UI的呈现
3)一般保存在containers文件夹下
1.下载安装react-reducx
npm i react-reducx -S
2.在src下创建组件文件夹,为了简化文件将UI组件和容器组件合并在一起例如:
3.相关的API,Provider:让所有组件都可以得到state数据,在入口文件index.js中
import React from 'react' import ReactDOM from 'react-dom' import App from './App' import store from './redux/store' import {Provider} from 'react-redux' ReactDOM.render( /* 此处需要用Provider包裹App,目的是让App所有的后代容器组件都能接收到store */ <Provider store={store}> <App/> </Provider>, document.getElementById('root') )
4.创建redux文件例如:
其中action用于调用reducer方法,
action中count.js
/* 该文件专门为Count组件生成action对象 */ import {INCREMENT,DECREMENT} from '../constant' //同步action,就是指action的值为Object类型的一般对象 export const increment = data => ({type:INCREMENT,data}) export const decrement = data => ({type:DECREMENT,data}) //异步action,就是指action的值为函数,异步action中一般都会调用同步action,异步action不是必须要用的。 export const incrementAsync = (data,time) => { return (dispatch)=>{ setTimeout(()=>{ dispatch(increment(data)) },time) } }
reducers中的count.js
/* 1.该文件是用于创建一个为Count组件服务的reducer,reducer的本质就是一个函数 2.reducer函数会接到两个参数,分别为:之前的状态(preState),动作对象(action) */ import {INCREMENT,DECREMENT} from '../constant' const initState = 0 //初始化状态 export default function countReducer(preState=initState,action){ // console.log('countReducer@#@#@#'); //从action对象中获取:type、data const {type,data} = action //根据type决定如何加工数据 switch (type) { case INCREMENT: //如果是加 return preState + data case DECREMENT: //若果是减 return preState - data default: return preState } }
reducers中index.js是一个将多个reducer合并到一个文件下
/* 该文件用于汇总所有的reducer为一个总的reducer */ //引入combineReducers,用于汇总多个reducer import {combineReducers} from 'redux' //引入为Count组件服务的reducer import count from './count' //引入为Person组件服务的reducer import persons from './person' //汇总所有的reducer变为一个总的reducer export default combineReducers({ count, persons })
然后在store.js中引入并暴露store
/* 该文件专门用于暴露一个store对象,整个应用只有一个store对象 */ //引入createStore,专门用于创建redux中最为核心的store对象 import {createStore,applyMiddleware} from 'redux' //引入汇总之后的reducer import reducer from './reducers' //引入redux-thunk,用于支持异步action import thunk from 'redux-thunk' //引入redux-devtools-extension import {composeWithDevTools} from 'redux-devtools-extension' //暴露store export default createStore(reducer,composeWithDevTools(applyMiddleware(thunk)))
5.connect:用于包装UI组件生成容器组件
import React, { Component } from 'react' //引入action import { increment, decrement, incrementAsync } from '../../redux/actions/count' //引入connect用于连接UI组件与redux import {connect} from 'react-redux' class Count extends Component { increment= () => { const {value} = this.selectNumber this.props.increment(value*1) }, decrement= () => { const {value} = this.selectNumber this.props.decrement(value*1) }, incrementAsync= () => { const {value} = this.selectNumber this.props.incrementAsync(value*1,500) } } render() { //console.log('UI组件接收到的props是',this.props); return ( <div> <h2>我是Count组件,下方组件总人数为:{this.props.renshu}</h2> <h4>当前求和为:{this.props.count}</h4> <button onClick={this.increment}>+</button> <button onClick={this.decrement}>-</button> <button onClick={this.incrementAsync}>异步加</button> </div> ) } //使用connect()()创建并暴露一个Count的容器组件 export default connect( state => ({//mapStateToprops将外部的数据(即state对象,放在reducer文件夹下的index导出的对象)转换为UI组件的标签属性 count:state.count, personCount:state.persons.length//在count组件中就可以取到person组件store中的值 }), {increment,decrement,incrementAsync} //mapDispatchToProps:将分发action的函数转换为UI组件的标签属性 )(Count)