简单说明一下,react hooks 是一个已经在提议中的新功能,预计会随着React 16.7.0一块儿发布。 /以上所述全部React均指ReactJS,下述会用React简称/javascript
要明白什么是React Hooks,那可能先了解一下它的两个替代品HOC和FaCC/Render Propshtml
若是咱们有一个须要共享的状态,须要在多个组件之间传递。咱们会怎么作? 或者说,当多个组件有公用的部分的时候,咱们会选择怎么作?前端
例如:java
// ComponentA
import React, { Component } from "react";
export default class ComponentA extends Component {
state = { toggle: false };
click = () => {
this.setState({ toggle: !this.state.toggle });
};
render() {
const { toggle } = this.state;
return (
<div className="App"> <button onClick={this.click}>Toggle Name</button> {toggle && <div>ComponentA</div>} </div>
);
}
}
复制代码
这里咱们举一个极端的例子,让ComponentB和A作同样的事情react
// ComponentB
export default class ComponentB extends Component {
state = { toggle: false };
click = () => {
this.setState({ toggle: !this.state.toggle });
};
render() {
const { toggle } = this.state;
return (
<div className="App"> <button onClick={this.click}>Toggle Name</button> {toggle && <div>ComponentB</div>} </div>
);
}
}
复制代码
能够看到代码重复的部分很是多,只有文字显示的不一样而已。 这里就须要用到HOC了。后端
使用HOC以后,变成api
// ComponentA
import React, { Component } from "react";
import HOC from "./HOC";
class ComponentA extends Component {
render() {
return <div>ComponentA</div>;
}
}
export default HOC(ComponentA);
复制代码
ComponentB同上。前端框架
这里HOC的写法就是提出共有的部分,接收一个Component进行渲染。app
const HOC = WrapperComponent =>
class HOC extends Component {
state = { toggle: false };
click = () => {
this.setState({ toggle: !this.state.toggle });
};
render() {
const { toggle } = this.state;
return (
<div className="App"> <button onClick={this.click}>Toggle Name</button> {toggle && <WrapperComponent />} </div>
);
}
};
export default HOC;
复制代码
能够发现,让公用的部分提取了出去,而且让代码看起来更简单舒服了一些。每个组件只须要关注本身内部的状态,而公有的部分以及共享状态的部分就交给HOC去解决。 这样不论再加多少个相似的Component,都无需大量的写重复代码了。框架
原理和HOC差很少,只是运用到了一个叫作 children的react props 能够讲代码简化成
//ComponentA
export default class ComponentA extends Component {
render() {
return <FaCC>{toggle => toggle && <div>ComponentA</div>}</FaCC>;
}
}
复制代码
//FACC
export default class FaCC extends Component {
state = { toggle: false };
click = () => {
this.setState({ toggle: !this.state.toggle });
};
render() {
const { toggle } = this.state;
return (
<div className="App"> <button onClick={this.click}>Toggle Name</button> {this.props.children(toggle)} </div>
);
}
}
复制代码
Render Props是用的同样的方法,只是换了别的属性,不用children而已
经过上述的行为,咱们已经发现了,它们能够共用不少部分的代码。 若是再深刻思考一下,就能够想到,在复杂的业务逻辑里面,若是发送同一个API请求的haul,咱们不该该在每个独立component里面发送一个请求。由于它们共享了同一个state,这样会形成资源的浪费。 咱们将HOC的部分代码更改一下,例如:
const HOC = WrapperComponent =>
class HOC extends Component {
state = { toggle: false, data: {} };
fetchData = () => {
fetch("/api", params).then(response => {
const { data } = data;
this.setState(data);
});
};
componentDidMount(){
this.fetchData();
}
render() {
/*......*/
};
export default HOC;
复制代码
在Hooks里面利用它的Effect,可让咱们使用到和Component同样的部分生命周期。 关于ReactHooks的详细介绍,我会在别的文章进行详细描述。 在这里,我想进行的是React Hooks,HOC,FACC的比较。
那么若是想实现上述功能,React Hooks会怎么作呢?
// Hooks
import { useState, useEffect } from "react";
const useHooks = () => {
const [data, setData] = useState(null);
const fetchData = () => {
fetch("/api", params).then(response => {
const { data } = data;
setData(data);
});
};
// Effect,这里至关于componentDidMount
useEffect(() => {
fetchData();
});
return data;
};
export default useHooks;
复制代码
在Component中须要用到公用的这个data的时候,咱们只须要这样作
// 这一行即是调用data的方法了
const data = Hooks();
return <div>{data}</div>;
复制代码
使用HOC们,去除掉了重复应用的问题。 但是打开React Dev Tool,咱们会发现,咱们的DOM结构却也更复杂了。 从
变成
再到
我想经过上述的代码比对,不可贵出这个结论。
试想一下,在一个庞大项目里面,普遍使用HOC们,会带来什么样的代码复杂度?
正如我在前文描述的那样,不管是HOC仍是FACC/Render Props,都有本身的技术上手难度以及理解困难的地方。 可是React Hooks的出现解决了这些问题。
必定有人不赞同,不负责任的猜想大概缘由以下
个人解答以下
而我认为目前前端框架里面,能察觉到用简单的方式来处理日趋复杂的业务,这件事的,Angular, Vue 都尚未作到。 Angular很是完整,可是学习曲线相对陡。 Vue正在面临整库重写。 只有React,用简单的方式来处理复杂业务,而且第三方库生态链很是庞大。
因此,我看好它。