问题引入
react组件提供了高端组件这么一个说法,高端组件可以部分替代组件之间的继承。是一个修饰器的模式,能够更灵活的处理一些组件复用的问题。
高阶组件本质是一个函数,此函数接受一个组件,返回一个新组件。
现在有这样一个需求,我们有很多业务,比如用户选择,订单选择,产品选择等。但是选择方式都是通过一个select选择框进行选择的,那么,可以将这个选择框提炼为一个公共组件,各个业务分装为业务组件,在一个实际的操作页面上,只要引入业务组件即可使用所有的功能。
这样的好处有:
- 新建一个业务组件特别简单,传入业务的url,名称和显示字段后,即可配合通用组件实现一个完整的select选择器。
- 提高代码的复用性,方便灵活的部署,修改基础组件的逻辑,对所有业务组件产生作用。
操作
基础组件
jsx1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| class BaseInputComp extends Component<BaseProp, BaseState> { componentDidMount() { const { dispatch } = this.props; dispatch({ type: 'productBrandList/fetchList', payload: { pageSize: 10, }, }); }
render() { const {children}=this.props function handleChange(value: any) { console.log(`Selected: ${value}`); } const x = 2 const {url} = this.props return ( <div> <Select size="default" mode="multiple" placeholder="Please select" maxTagCount={x} defaultValue={[]} onChange={handleChange} style={{width: '250px'}} > {children} </Select> {url} </div> ); } }
export default BaseInputComp;
|
基础组件中的高阶组件,提供给人员组件用来进行封装。
jsx1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| export function withPersistentData(name: string, url: string) { return (WrappedComponent: any) => { class NewComponent extends Component<BaseProp, BaseState> { render() { return ( <div> <span>{name}选择</span> <WrappedComponent url={url}{...this.props}/> </div> ) } }
return NewComponent } }
|
人员组件
jsx1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| import React, {Component} from "react"; import BaseInputComp, {withPersistentData} from "@/components/BaseInputComp"; import {BaseProp, BaseState} from "@/components/BaseInputComp/model";
interface UserProp extends BaseProp { } interface UserState extends BaseState{ } @withPersistentData('人员','/product/info') export default class UserComp extends Component<UserProp, UserState> { render() { return ( <BaseInputComp {...this.props}></BaseInputComp> ) } }
|
使用方法
jsx1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| interface ListProps extends BaseProp { userId: number dispath:Dispatch }
interface ListState extends BaseState { }
@connect(({exampleDemoModel}: { exampleDemoModel: ExampleDemoType }) => ({userId: exampleDemoModel.userId})) class ComponentDemo extends Component<ListProps, ListState> { enterIconLoading = () => { const {dispatch} = this.props; const {userId} = this.props dispatch({ type: "exampleDemoModel/fetchNum", payload2: { numCount: userId, } }) }; render() { const {userId} = this.props return ( <div> 当前userId:{userId}<br/><br/> <Button onClick={this.enterIconLoading}>切换UserId</Button><br/><br/> <UserComp {...this.props}/> </div> ) }
}
export default Form.create<ListProps & FormComponentProps>()(ComponentDemo);
|
最后更新时间:
这里可以写作者留言,标签和 hexo 中所有变量及辅助函数等均可调用,示例:
http://trembear.github.io/2019/11/09/前端/高阶组件/