在多个组件有共用数据时,结合redux封装高阶组件,实现逻辑复用,简化代码,做下笔记理解学习高阶组件的思想!
- 通过脚手架快速生成项目文件
npx create-react-app learn
// 或者
npm i create-react-app
create-react-app learn
- 使用redux创建store容器存储数据, reducer定义相应处理事件, 通过dispatch分发事件
import { createStore } from "redux"; // 注意此用法redux官方已经废弃, 只是为了方便理解,暂不更改
const initialState = { counter: 0}
const reducer = ((state = initialState, action) => {
switch (action.type) {
case 'INCREMENT':
return {...state, counter: state.counter + 1}
case 'DECREMENT':
return {...state, counter: state.counter - 1 }
case 'ADD_NUMBER':
return {...state, counter: state.counter + action.number}
case 'SUB_NUMBER':
return {...state, counter: state.counter - action.number}
default:
return state;
}
})
const store = createStore(reducer);
export default store
3.定义Home组件
import React from 'react';
import { connect } from '../utils/connect';
const mapStateToProps = state => ({counter: state.counter})
const mapDispatchToProps = dispatch => ({
increment: () => dispatch({type: 'INCREMENT'}),
addNumber: number => dispatch({type: 'ADD_NUMBER', number})
})
function Home(props) {
return (
<div>
<h1> Home </h1>
<h2> 当前计数: {props.counter} </h2>
<button onClick={ e => props.increment()}> +1 </button>
{/* props.increment() 等于 increment: () => dispatch({type: 'INCREMENT'})*/}
<button onClick={ e => props.addNumber(5)}> +5 </button>
</div>
)
}
export default connect(mapStateToProps, mapDispatchToProps)(Home)
// 1. Home组件接收props
// 2. 导出时 经由 高阶组件 包装后导出
// 3. 高阶组件 包装后 可以 合并自定义的props和dispatch函数给Home组件
// 4.
- 定义connect高阶函数生成高阶组件
import { PureComponent } from 'react'
import store from '../store/index'
export function connect(mapStateProps, mapDispatchToProp){
return function enhanceHOC(WrappedComponent){
return class extends PureComponent{
constructor(props){
super(props)
this.state = {
storeState: mapStateProps(store.getState())
}
}
componentDidMount(){ // 此处订阅是为了调用setState 从而触发render 实现数据变化 组件重新渲染
this.unSubscribe = store.subscribe(()=>{ // 此函数会返回一个卸载自身取消订阅的函数
this.setState({ storeState: mapStateProps(store.getState()) })
})
}
componentWillUnmount(){
this.unSubscribe()
}
render(){
// return <WrappedComponent {...this.props} {...this.state.storeState} {...mapDispatchToProp(store.dispatch)}/>
return <WrappedComponent {...this.props} {...mapStateProps(store.getState())} {...mapDispatchToProp(store.dispatch)}/>
// 此处高阶组件将新增props和原组件props分别解构进行传递 同时传递dispatch事件
// 此处神奇之处在于mapDispatchToProp实现了将dispatch函数预先传递给组件 彷佛跳过了dispatch事件
}
}
}
}
// 将传递进来的组件 进行包裹 同时携带传递过来的参数 一起 导出