高阶组件不是组件,而是一个普通的函数,传入一个组件,返回一个新的组件。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','用户名');
复制代码