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文件中获取数据。
相关文章
相关标签/搜索