高階組件不是組件,而是一個普通的函數,傳入一個組件,返回一個新的組件。react
構想一個使用場景(留言板):ajax
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','手機號');
複製代碼
這樣就能夠實現組件邏輯的封裝。
若是高階組件的數據經過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"
}
複製代碼
若是想經過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','用戶名');
複製代碼