看了一篇文章,也說清了 React 發展歷程,我一直都堅信任何技術方案的出現都是爲了以更好的方式解決問題。html
React 組件基本能夠歸結三個階段:react
示例:數組
const Index = React.createClass({ getDefaultProps() { return {}; }, getInitialState() { return { name: "robin" }; }, render() { return <div></div>; } });
這是早期建立組建的方式,我想當時 JavaScript 尚未內置的類系統。當 ES6 到來的時候,這一切都改變了。ide
示例:函數
class Index extends React.Component { constructor(props) { super(props); this.state = { name: "robin" }; } render() { return <div></div>; } }
初始化屬性及狀態的方式隨之發生了變化,這裏或許會有疑問,createClass 用的好好地,爲何還要使用以 Class 繼承的方式編寫組件,我想應該是爲了迎合 ES 的發展。post
隨着項目的的複雜度提高,若是項目中所有使用類的方式開發組件是否是有點重,這個時候它來了。this
示例:spa
const Button = props => { return <div></div>; };
我只是要封裝個公共組件,用它就夠。code
夜黑風高夜,組件開發時……htm
想這種複合型組件就須要狀態的介入,可是又犯不着使用類組件,所以誕生了 React Hooks
若是須要操做狀態,代碼以下:
import React, { useState } from "react"; export default function TextInput() { const [name, setName] = useState(""); return <input value={name} onChange={e => setName(e.target.value)} />; }
若是須要共享狀態,代碼以下:
const AppContext = React.createContext({}); const Button1 = () => { const { name } = useContext(AppContext); return <div>{name}</div>; }; const Button2 = () => { const { name, age } = useContext(AppContext); return ( <div> {name} {age} </div> ); }; const Button3 = () => { const [name, setName] = useState("robin111"); return ( <AppContext.Provider value={{ name: name, age: 29 }} > <Button1 /> <Button2 /> <button onClick={() => setName("test")}>211</button> </AppContext.Provider> ); };
當共享狀態組件嵌套時,當前的 context 值由上層組件中距離當前組件最近的 <AppContext.Provider> 的 value prop 決定。
Redux 提供了狀態管理方案,在這裏你也可使用 useReducer。
const [state, dispatch] = useReducer(reducer, initialArg, init);
借鑑了阮一峯老師的計數器實例:
const myReducer = (state, action) => { switch (action.type) { case "countUp": return { ...state, count: state.count + 1 }; default: return state; } }; function App() { const [state, dispatch] = useReducer(myReducer, { count: 0 }); return ( <div className="App"> <button onClick={() => dispatch({ type: "countUp" })}>+1</button> <p>Count: {state.count}</p> </div> ); }
官方描述:Effect Hook 可讓你在函數組件中執行反作用操做。
import React, { useState, useEffect } from "react"; function Example() { const [count, setCount] = useState(0); useEffect(() => { document.title = `You clicked ${count} times`; }); return ( <div> <p>You clicked {count} times</p> <button onClick={() => setCount(count + 1)}>Click me</button> </div> ); }
這段代碼是官方提供的,簡潔明瞭。
官方在 Effect 方面介紹的很詳細,強烈推薦你們詳讀。中文社區詳解
自定義的目的,是爲了封裝重複邏輯,共享邏輯,既然是自定義 Hooks,也不是簡單函數封裝,固然被封裝的邏輯代碼中也須要包含官方提供的 Hook 方案,方能湊效。中文社區詳解
剛開始在項目中使用,還未能深刻使用,只能列舉目前能用到的示例代碼,自定義 Hooks,在我看來是對 Hooks 的組合封裝。
參考文章: