高阶函数定义
如果一个函数符合下面2个规范中的任何一个,那该函数就是高阶函数。
1.若A函数,接收的参数是一个函数,那么A就可以称之为高阶函数。
2.若A函数,调用的返回值依然是一个函数,那么A就可以称之为高阶函数。
简单理解就是:
高阶函数是一个特别的函数,接受函数类型的参数,返回值是也是函数
常见的高阶函数有
a. 定时器: setTimeout()/setInterval()
b. Promise: Promise(() => {}) then(value => {}, reason => {})
c. 数组遍历相关的方法: forEach()/filter()/map()/reduce()/find()/findIndex()
d. 函数对象的bind()
e. Form.create()() / getFieldDecorator()()
我现在编写一个高阶函数的实例,需求是这样,在输入框输入相应值,点击确定
按钮弹出输入的值
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>高阶函数_函数柯里化</title>
</head>
<body>
<!-- 准备好一个“容器” -->
<div id="test"></div>
<!-- 引入react核心库 -->
<script type="text/javascript" src="../js/react.development.js"></script>
<!-- 引入react-dom,用于支持react操作DOM -->
<script type="text/javascript" src="../js/react-dom.development.js"></script>
<!-- 引入babel,用于将jsx转为js -->
<script type="text/javascript" src="../js/babel.min.js"></script>
<script type="text/babel">
//创建组件
class Login extends React.Component {
//初始化状态
state = {
username: '', //用户名
password: '', //密码
};
//保存表单数据到状态中
saveFormData = (dataType) => { //saveFormData这个就是一个高阶函数
return (event) => {
this.setState({ [dataType]: event.target.value });
};
};
//表单提交的回调
handleSubmit = (event) => {
event.preventDefault(); //阻止表单提交
const { username, password } = this.state;
alert(`你输入的用户名是:${username},你输入的密码是:${password}`);
};
render() {
return (
<form onSubmit={this.handleSubmit}>
用户名:
<input
onChange={this.saveFormData('username')}
type="text"
name="username"
/>
密码:
<input
onChange={this.saveFormData('password')}
type="password"
name="password"
/>
<button>登录</button>
</form>
);
}
}
//渲染组件
ReactDOM.render(<Login />, document.getElementById('test'));
</script>
</body>
</html>
以上saveFormData这个就是一个高阶函数,因为它满足高阶函数的定义条件。
高阶组件的定义
高阶组件(HOC)就是接受一个组件作为参数并返回一个新组件的函数。这里需要注意高阶组件是一个函数,并不是组件,这一点一定要注意。
同时这里强调一点高阶组件本身并不是 React API。它只是一种模式,这种模式是由 React 自身的组合性质必然产生的。
简单理解就是: 本质就是一个函数定义,且该函数接受一个组件作为参数,并返回一个新的组件。
1、最普通的组件
welcome函数转为react组件。
import React, {Component} from 'react'
class Welcome extends Component {
constructor(props) {
super(props);
this.state = {
username: ''
}
}
componentWillMount() {
let username = localStorage.getItem('username');
this.setState({
username: username
})
}
render() {
return (
<div>welcome {this.state.username}</div>
)
}
}
export default Welcome;
goodbey函数转为react组件。
import React, {Component} from 'react'
class Goodbye extends Component {
constructor(props) {
super(props);
this.state = {
username: ''
}
}
componentWillMount() {
let username = localStorage.getItem('username');
this.setState({
username: username
})
}
render() {
return (
<div>goodbye {this.state.username}</div>
)
}
}
export default Goodbye;
我们发现两个组件中有一句代码是一样的,这叫冗余。
我们来写一个高阶组件(高阶组件就是一个函数,且该函数接受一个组件作为参数,并返回一个新的组件)。
import React, {Component} from 'react'
export default (WrappedComponent) => {
class NewComponent extends Component {
constructor() {
super();
this.state = {
username: ''
}
}
componentWillMount() {
let username = localStorage.getItem('username');
this.setState({
username: username
})
}
render() {
return <WrappedComponent username={this.state.username}/>
}
}
return NewComponent
}
这样我们就能简化Welcome组件和Goodbye组件。
import React, {Component} from 'react';
import wrapWithUsername from 'wrapWithUsername';
class Welcome extends Component {
render() {
return (
<div>welcome {this.props.username}</div>
)
}
}
Welcome = wrapWithUsername(Welcome);
export default Welcome;
import React, {Component} from 'react';
import wrapWithUsername from 'wrapWithUsername';
class Goodbye extends Component {
render() {
return (
<div>goodbye {this.props.username}</div>
)
}
}
Goodbye = wrapWithUsername(Goodbye);
export default Goodbye;
高阶组件就是把username通过props传递给目标组件了。目标组件只管从props里面拿来用就好了。
例子2
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>高阶组件例子</title>
</head>
<body>
<!-- 准备好一个“容器” -->
<div id="test"></div>
<!-- 引入react核心库 -->
<script type="text/javascript" src="../js/react.development.js"></script>
<!-- 引入react-dom,用于支持react操作DOM -->
<script
type="text/javascript"
src="../js/react-dom.development.js"
></script>
<!-- 引入babel,用于将jsx转为js -->
<script type="text/javascript" src="../js/babel.min.js"></script>
<script type="text/babel">
function withHeader(WrappedComponent) {
return class HOC extends React.Component {
render() {
return (
<div>
<legend>默认标题</legend>
<WrappedComponent {...this.props} />
</div>
);
}
};
}
class Demo extends React.Component {
render() {
return <div>我是一个普通组件</div>;
}
}
const WithHeaderDemo = withHeader(Demo);
//渲染组件
ReactDOM.render(<WithHeaderDemo />, document.getElementById('test'));
</script>
</body>
</html>