看了一篇文章,也说清了 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 的组合封装。
参考文章: