国外建设网站的软件,北京网站开发品牌,怎么推广产品最有效,app定制开发制作React 基础巩固(三十七)——自定义connect高阶组件
一、手撸一个自定义connect高阶组件
import { PureComponent } from react;
import store from ../store;/*** connect的参数#xff1a;* 参数一#xff1a; 函数* 参数二#xff1a; 函数* 返…React 基础巩固(三十七)——自定义connect高阶组件
一、手撸一个自定义connect高阶组件
import { PureComponent } from react;
import store from ../store;/*** connect的参数* 参数一 函数* 参数二 函数* 返回值 函数*/
export default function connect(mapStateToProps, mapDispatchToProps) {// 返回一个高阶组件本质也是函数return function (WrapperComponent) {class NewComponent extends PureComponent {constructor(props) {super(props);// 将接收到的mapStateToProps赋给state用于部分值修改时的浅层比较、更新statethis.state mapStateToProps(store.getState());}componentDidMount() {this.unsubscribe store.subscribe(() {this.setState(mapStateToProps(store.getState()));});}componentWillUnmount() {this.unsubscribe();}render() {// 将接收到的mapStateToProps、mapDispatchToProps传入要返回的新组件中const stateObj mapStateToProps(store.getState());const dispatchObj mapDispatchToProps(store.dispatch);return (WrapperComponent {...this.props} {...stateObj} {...dispatchObj} /);}}return NewComponent;};
}
二、目前的问题
import store from ../store;从这行代码可以看到目前的connect直接引用了上级目录的store过于依赖目前既定的store这样不利于复用。假设另一个项目的store所在位置不在上级目录中则会出现问题。
三、优化上面的丐版connect
为了让所有人都能使用我们应该把这种“写死”的做法换成让开发者自己传入一个store 构建一个StoreContext用于创建Store的上下文src/hoc/StoreContext.js: import { createContext } from react;export const StoreContext createContext()当我们在项目的index.js中引入connect时引入并使用该上下文让开发者手动传入当前的storesrc/index.js import React from react;
import ReactDOM from react-dom/client;
import { Provider } from react-redux;
import { StoreContext } from ./hoc;
import App from ./App;
import store from ./store;const root ReactDOM.createRoot(document.getElementById(root));
root.render(// React.StrictModeProvider store{store}StoreContext.Provider value{store}App //StoreContext.Provider/Provider// /React.StrictMode
); 在connect中通过 contextType 共享从 Provider 中传入的 store 变量将原来直接引用的 store 替换成 this.contexthoc/connect.js import { PureComponent } from react;
import { StoreContext } from ./StoreContext;/*** connect的参数* 参数一 函数* 参数二 函数* 返回值 函数*/
export function connect(mapStateToProps, mapDispatchToProps) {// 返回一个高阶组件本质也是函数return function (WrapperComponent) {class NewComponent extends PureComponent {constructor(props, context) {super(props);// 将接收到的mapStateToProps赋给state用于部分值修改时的浅层比较、更新statethis.state mapStateToProps(context.getState());}componentDidMount() {this.unsubscribe this.context.subscribe(() {this.setState(mapStateToProps(this.context.getState()));});}componentWillUnmount() {this.unsubscribe();}render() {// 将接收到的mapStateToProps、mapDispatchToProps传入要返回的新组件中const stateObj mapStateToProps(this.context.getState());const dispatchObj mapDispatchToProps(this.context.dispatch);return (WrapperComponent {...this.props} {...stateObj} {...dispatchObj} /);}}// 在类组件中通过 contextType 共享store变量NewComponent.contextType StoreContextreturn NewComponent;};
} 最后在hoc中构建index.js将优化后的connect导出hoc/index.js export { StoreContext } from ./StoreContext;
export { connect } from ./connect; 在界面中使用现在优化后的connect import React, { PureComponent } from react;
import { connect } from ../hoc;
import { addNumber } from ../store/features/counter;export class About extends PureComponent {render() {const { counter } this.props;return (divh2About Counter: {counter}/h2/div);}
}const mapStateToProps (state) ({counter: state.counter.counter,
});const mapDispatchToProps (dispatch) ({addNumber(num) {dispatch(addNumber(num));},
});export default connect(mapStateToProps, mapDispatchToProps)(About); 查看效果与之前效果一致