react高階組件

高階組件不是組件,而是一個普通的函數,傳入一個組件,返回一個新的組件。react

構想一個使用場景(留言板):ajax

暱稱和手機號能夠不改變,內容改變。

1.高階組件的實現

import React,{Component} from 'react';
import ReactDOM from 'react-dom';
import UserName from './UserName';
import Mobile from './Mobile';
 export default class Memo extends Component{
     render(){
         return (
             <form>
                  <UserName/>
                  <Mobile/>
                  留言 <textarea></textarea>  
             </form>
         )
     }
 }
複製代碼

當填寫用戶名和手機號後刷新頁面,用戶名和手機號依然存在。實現:將這兩個值保存到localstorage中,刷新後從新加載。json

username組件bash

import React,{Component} from 'react';
class UserName extends Component{
    componentDidMount(){
        this.username.value=localStorage.getItem('username')||'請輸入暱稱';
    }
    handleChange=(event)=>{
        localStorage.setItem('username',event.target.values())
    }
    render(){
        return <label>用戶名<input ref={input=>this.username=input} onChange={this.handleChange}  /><br/></label>
    }
}
export default UserName;
複製代碼

1.若是還須要手機號,qq號等和username組件有相同邏輯的組件,會形成代碼重複。 2.若是要改變這套邏輯,全部的組件都要修改。dom

這時須要用到高階組件去複用相同的邏輯:函數

高階組件就是一個函數,用來封裝重複的邏輯。
傳進去一個老組件,返回一個新組件fetch

高階組件ui

import React,{Component} from 'react';
export default function(OldComponent,name,placeholder){
      class NewComponent extends Component{
        constructor(){
            super();
            this.state = {data:''};
        }  
        componentWillMount(){
            this.setState({data:localStorage.getItem(name)||placeholder});
        }
        save=(event)=>{
            localStorage.setItem(name,event.target.values())
        }
        render(){
            return <OldComponent data={this.state.data} save={this.save}/>
        }
      }
      return NewComponent;
}
複製代碼

改造username組件this

import React,{Component} from 'react';
import local from './local';
class UserName extends Component{
    render(){
        return <label>用戶名<input defaultValue={this.props.data}  onChange={this.props.save}/><br/></label>
    }
}
export default local(UserName,'username','用戶名');
複製代碼

Mobile組件spa

import React,{Component} from 'react';
import local from './local';
class Mobile extends Component{
    render(){
        return <label>手機號<input defaultValue={this.props.data}  onChange={this.props.save}/><br/></label>
    }
}
export default local(Mobile,'mobile','手機號');
複製代碼

這樣就能夠實現組件邏輯的封裝。

2.增長需求,再次改造高階組件

若是高階組件的數據經過fetch從後臺獲取。須要怎樣修改。

fetch高階組件

import React,{Component} from 'react';
export default function(OldComponent,name,placeholder){
      class NewComponent extends Component{
        constructor(){
            super();
            this.state = {data:''};
        }  
        componentWillMount(){
            fetch('/user.json').then(response=>response.json()).then(user=>{
                this.setState({data:user[name]||placeholder});
            });
           
        }
        save=(event)=>{
            localStorage.setItem(name,event.target.values())
        }
        render(){
            return <OldComponent data={this.state.data}  />
        }
      }
      return NewComponent;
}
複製代碼

user.json

{
    "username": "xxxxxx",
    "mobile": "15711111111"
}
複製代碼

3.高階組件中的值從localhost和fetch共同獲取

若是想經過locahost獲取username的值:xx。再使用xx從後臺獲取數據。

username -> xx -> 張三

爲了簡化省略save方法,localstorage中已經有了username:xx。着重看一下邏輯。

user.json

{
    "xx": "張三",
    "mobile": "15711111111"
}
複製代碼

Username組件

import React,{Component} from 'react';
import ajax from './ajax';
import local from './local';
class UserName extends Component{
    render(){
        return <label>用戶名<input value={this.props.data}  /><br/></label>
    }
}
UserName = ajax(UserName,'username','用戶名');
UserName = local(UserName,'username','用戶名');
export default UserName;
複製代碼

Ajax高階組件

import React,{Component} from 'react';
export default function(OldComponent){
      class NewComponent extends Component{
        constructor(){
            super();
            this.state = {data:''};
        }  
        componentWillMount(){
            fetch('/user.json').then(response=>response.json()).then(user=>{
                this.setState({data:user[this.props.data]});
            });
           
        }
        render(){
            return <OldComponent data={this.state.data}  />
        }
      }
      return NewComponent;
}
複製代碼

local高階組件

import React,{Component} from 'react';
export default function(OldComponent,name,placeholder){
      class NewComponent extends Component{
        constructor(){
            super();
            this.state = {data:''};
        }  
        componentWillMount(){
            this.setState({data:localStorage.getItem(name)||placeholder});
        }
        render(){
            return <OldComponent data={this.state.data} />
        }
      }
      return NewComponent;
}
複製代碼

爲何ajax方法要在local方法上呢?(着重注意)

UserName = ajax(UserName,'username','用戶名');
UserName = local(UserName,'username','用戶名');
複製代碼

由於這是組件的封裝:先使用ajax封裝,而後用local封裝。等到組件渲染的時候,就是從外向內執行,先執行local,從localstorage中獲取到xx。而後經過ajax,使用xx在json文件中獲取數據。
相關文章
相關標籤/搜索