当我们使用redux的时候,可能会出现不同组件中有很多重复的redux代码,官方给我们封装了一个react-redux来解决这个问题
第一步肯定就是安装了
yarn add react-redux
创建组件
about.js
import React, { PureComponent } from 'react'
import {connect} from 'react-redux'
import {
subAction,
getHomeMultidataAction
} from '../store/actionCreators'
class about extends PureComponent {
render(){
return (
about
当前:{this.props.counter}
)
}
}
const mapStateToProps = state =>{
return {
counter:state.counter,
banners:state.banners,
recommends:state.recommends
}
};
const mapDispachToProp = dispatch =>{
return {
decreament(){
dispatch(subAction(1))
},
removenumber(num){
dispatch(subAction(num))
},
getHomeMultidata(){
dispatch(getHomeMultidataAction)
}
}
};
export default connect(mapStateToProps,mapDispachToProp)(about)
创建一个store文件夹,专门放redux代码
index.js
import {createStore} from 'redux'
import reducer from './reducer.js'
const store = createStore(reducer)
export default store
reducer.js
import {
SUB_NUMBER,
} from './constants.js'
const defaultState = {
counter: 0,
}
function reducer(state = defaultState, action) {
switch (action.type) {
case SUB_NUMBER:
return { ...state, counter: state.counter - action.num }
default:
return state
}
}
export default reducer
constants.js
export const SUB_NUMBER = "SUB_NUMBER"
actionCreators.js
import {
SUB_NUMBER,
} from './constants.js'
export const subAction = num =>({
type:SUB_NUMBER,
num
})
这样就好了,当我们在别的组件里面就不用写类似这样的代码了
constructor(props){
super(props);
this.state={
counter:store.getState().counter
}
}
//订阅
componentDidMount(){
this.unsubscribe = store.subscribe(()=>{
this.setState({
counter:store.getState().counter
})
})
}
//取消订阅
componentWillUnmount(){
this.unsubscribe()
}
再来说一下redux-thunk
当我们有从接口请求的数据需要存储到redux中时候,我们可以直接在redux发送网络请求,相当于一个中间件,当我们请求的时候可以做一些事,类似expree和koa
首先安装
yarn add redux-thunk
在主index.js中
import {Provider} from 'react-redux'
ReactDOM.render(
,document.querySelector('#root'))
在上面创建的store中的index.js中这样写
import {createStore,applyMiddleware} from 'redux'
import thunkMiddleware from 'redux-thunk'
import reducer from './reducer.js'
//应用一些中间件
const storeEnhancer = applyMiddleware(thunkMiddleware)
const store = createStore(reducer,storeEnhancer)
export default store
actionCreators.js中
import axios from 'axios'
import {
CHANGE_BANNERS
} from './constants.js'
export const getHomeMultidataAction = dispatch =>{
axios({
url:'',
}).then((res)=>{
console.log(res)
dispatch(changeBannersAction(data))
})
}
constants.js
export const CHANGE_BANNERS = "CHANGE_BANNERS"
reducer.js
import {
CHANGE_BANNERS
} from './constants.js'
const defaultState = {
banners:[]
}
function reducer(state = defaultState, action) {
switch (action.type) {
case CHANGE_BANNERS:
return {...state,banners:action.banners}
default:
return state
}
}
export default reducer
这样即可
在这我再说一下react-redux的怎么实现的
创建一个connect.js
import React,{ PureComponent } from "react"
import {StoreContext} from './context'
export function connect(mapStateToProps,mapDispachToProp){
return function enhanceHOC(WrappedComponent){
class EnhanceComponent extends PureComponent{
constructor(props,context){
super(props,context);
this.state ={
storeState:mapStateToProps(context.getState())
}
}
componentDidMount(){
this.unsubscribe = this.context.subscribe(()=>{
this.setState({
storeState:mapStateToProps(this.context.getState())
})
})
}
componentWillUnmount(){
this.unsubscribe()
}
render(){
return
}
}
EnhanceComponent.contextType = StoreContext
return EnhanceComponent
}
}
创建一个context.js
import React from 'react'
const StoreContext = React.createContext()
export{
StoreContext
}
在主index.js中
import {StoreContext} from './learn-redux2/utils/context'
ReactDOM.render(
,document.querySelector('#root'))
其实react-redux就是这样实现的