• React.js |高阶组件的应用


    什么是高阶组件

    高阶组件(HOC)是 React 中用于复用组件逻辑的一种技巧,让它重复的逻辑在许多组件中得到共享。简单的说,高阶组件是一个以组件作为参数,并返回新组件的函数。

    //其中WrapedComponent是包裹后的组件,wrapedComponent是高阶组件(函数),RawComponent是你想包裹的组件
    const WrapedComponent = wrapedComponent(RawComponent);
    

    应用场景1-更改props

    //WrapComponent.js(高阶组件)
    const wrapComponent = (OriginalComponent) => class extends Component{
        handleClick(){console.log('Well Done!')}
    	render(){
            const newProps={
    			say:'Click me!',
    			handleClick:this.handleClick
    		}
            //先是解构原来的,后面解构新加入的
    		return(
    			<OriginalComponent {...this.props} {...newProps}/>
    		)
    	}
    }
    
    //SayHi.js(原始组件)
    //1.引入高阶组件
    import wrapComponent from './WrapComponent'
    //2.原始组件
    function SayHi(props){
        return(
             <div>hello!{props.name}<br/><h1 onClick={props.handleClick}>{props.say}</h1></div>
        )
    }
    //3.导出包裹后的组件
    export default wrapComponent(SayHi)
    
    //App.js
    import SayHi from './SayHi'
    class App extends Component {
      render(){
        return(
          <SayHi name={'Lisa'}/>
        )
      }
    }
    

    image.png

    应用场景2-与其他组件一起包裹

    //传进来的组件在另一个组件OtherComponent中渲染,最后返回另一个组件OtherComponent
    //这意味着可以将一些常用的生命周期放在这里,那么在原来的组件就不必重复写
    function wrapComponent(OriginalComponent) {
        class OtherComponent extends React.Component {
          componentDidMount(){
    		console.log('常用的')
    	  }
          render() {
            return <OriginalComponent {...this.props}/>;
          }
        }
        return OtherComponent
    }
    

    应用场景3-抽离state

    一般写法:

    class Form extends React.Component{
            state = {user:"",psw:""}
            onUserChange = (e)=>{
                this.setState({user: e.target.value})
            }
            onPswChange = (e)=>{
                this.setState({psw: e.target.value})
            }
        render(){
            return(
                <div>
                    <div>
                       用户名:<input type="text" value={this.state.user} onChange={this.onUserChange}/>
                    </div>
                    <br/>
                    <div>
                        密码:<input type="text"  value={this.state.psw} onChange={this.onPswChange}/>
                    </div>
                    <div>
                        <p>变动:</p>
                         <p>{this.state.user}|{this.state.psw}</p>
                    </div>
                </div>
            )
        }
    }
    

    抽离state后的写法:

    const wrapComponent = (OriginalComponent) => class extends Component{
    	constructor(props) {
    		super(props)
    		this.state = {user:"",psw:""}
    		this.onUserChange = (e)=>{
    			this.setState({user: e.target.value})
    		}
    		this.onPswChange = (e)=>{
    			this.setState({psw: e.target.value})
    		}
    	  }
       
    	render(){
            const newProps={
    			user:{
    				value:this.state.user,
    				onChange: this.onUserChange,
    			},
    			psw:{
    				value:this.state.psw,
    				onChange: this.onPswChange
    			}	
    		}
    		return(
    			<OriginalComponent {...this.props} {...newProps}/>
    		)
    	}
    }
    
    //Form.js
    import wrapComponent from './WrapComponent'
    function Form(props){
        return(
            <div>
                <div>
                   用户名:<input type="text" {...props.user}/>
                </div>
                <br/>
                <div>
                    密码:<input type="text"  {...props.psw}/>
                </div>
                <div>
                    <p>变动:</p>
                     <p>{props.user.value}|{props.psw.value}</p>
                </div>
    		</div>
        )
    }
    export default wrapComponent(Form)
    

    image.png

    应用场景4-反向继承

    //WrapComponent.js
    function wrapComponent(OriginalComponent){
    	return class WrapComponent extends OriginalComponent{
    		componentDidMount(){
    			console.log(this.state)
    			this.setState({
    				count:1
    			})
    			setInterval(()=>{
    				this.setState({count:this.state.count+1})
    			}, 1000)
                //2.也可以继承其他。例如state,props,组件生命周期,以及渲染方法
                //下面是继承了一个生命周期
    			super.componentDidMount()
    		}
    		
    		render(){
    			//1.继承render
    			return super.render()
    		}
    	}
    }
    export default wrapComponent
    
    //Counter.js
    import wrapComponent from './WrapComponent'
    class Counter extends React.Component {
    	constructor(){
    		super();
    		this.state = {count : '无'}
    	}
        componentDidMount(){
    		console.log('有事吗?')
    	}
    	render(){
    		return (
    			<div>
    				{this.state.count}
    			</div>
    		)
    	}
    }
    export default wrapComponent(Counter)
    

    image.png
    默认只打印高阶组件里面的,只有当super了才会打印继承过来的。
    image.png

    应用场景5-利用反向继承劫持渲染

    把高阶组件的render变换一下,现在只要当传过来的start为true时才会渲染

    //WrapComponent.js
    render(){
        if (this.props.start) {
            return super.render()
        } else {
            return null
        }
        //return super.render()
    }
    
    //App.js
    import Counter from './Counter'
    class App extends Component {
      render(){
        return(
          <Counter start={true}/>
        )
      }
    }
    

    多个参数

    • 有时候高阶组件只接收一个参数

      const AfterWrap = wrapComponent(SayHi);
      
    • 也可以接收多个参数,比如接收配置对象用于指定组件的数据依赖:

      //假设 "DataSource" 是个全局范围内的数据源变量
      const BlogPostWithSubscription = withSubscription(
        BlogPost,
        (DataSource, props) => DataSource.getBlogPost(props.id)
      );
      
      //传进来的第二个参数实际上是能获取并返回数据的函数
      function withSubscription(WrappedComponent, selectData) {
        return class extends React.Component {
          constructor(props) {
            super(props);
            this.state = {
              data: selectData(DataSource, props)
            };
          }
       //...
          handleChange() {
            this.setState({
              data: selectData(DataSource, this.props)
            });
          }
        
          render() {
            return <WrappedComponent data={this.state.data} {...this.props} />;
          }
        };
      }
      

    该示例具体的看这里https://react.docschina.org/docs/higher-order-components.html

    参考

  • 相关阅读:
    ajax 中文乱码问题 主要是IE浏览器
    js 带省略号的分页源码及应用实例
    js iframe onload &line-height浏览器兼容问题
    Js 正则表达式特殊字符含义
    js prototype
    js call apply caller callee bind
    怎么查看一个网站是用什么语言编写的?
    ASP.NET之AreaRegistration
    产品经理
    程序猿全面充电10本书
  • 原文地址:https://www.cnblogs.com/sanhuamao/p/13744294.html
Copyright © 2020-2023  润新知