簡單說明一下,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,用簡單的方式來處理複雜業務,而且第三方庫生態鏈很是龐大。
因此,我看好它。