React Hooks 學習筆記

看了一篇文章,也說清了 React 發展歷程,我一直都堅信任何技術方案的出現都是爲了以更好的方式解決問題。html

React 組件發展歷程

React 組件基本能夠歸結三個階段:react

  • createClass Components
  • Class Components
  • Function Components

createClass Components

示例:數組

const Index = React.createClass({
  getDefaultProps() {
    return {};
  },
  getInitialState() {
    return {
      name: "robin"
    };
  },
  render() {
    return <div></div>;
  }
});

這是早期建立組建的方式,我想當時 JavaScript 尚未內置的類系統。當 ES6 到來的時候,這一切都改變了。ide

Class Components

示例:函數

class Index extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      name: "robin"
    };
  }

  render() {
    return <div></div>;
  }
}

初始化屬性及狀態的方式隨之發生了變化,這裏或許會有疑問,createClass 用的好好地,爲何還要使用以 Class 繼承的方式編寫組件,我想應該是爲了迎合 ES 的發展。post

隨着項目的的複雜度提高,若是項目中所有使用類的方式開發組件是否是有點重,這個時候它來了。this

Function Components

示例:spa

const Button = props => {
  return <div></div>;
};

我只是要封裝個公共組件,用它就夠。code

夜黑風高夜,組件開發時……htm

想這種複合型組件就須要狀態的介入,可是又犯不着使用類組件,所以誕生了 React Hooks

React Hooks 介紹

  • useState()
  • useContext()
  • useReducer()
  • useEffect()

useState

若是須要操做狀態,代碼以下:

import React, { useState } from "react";

export default function TextInput() {
  const [name, setName] = useState("");

  return <input value={name} onChange={e => setName(e.target.value)} />;
}

useContext

若是須要共享狀態,代碼以下:

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 決定。

useReducer

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>
  );
}

useEffect

官方描述: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

自定義的目的,是爲了封裝重複邏輯,共享邏輯,既然是自定義 Hooks,也不是簡單函數封裝,固然被封裝的邏輯代碼中也須要包含官方提供的 Hook 方案,方能湊效。中文社區詳解

總結

剛開始在項目中使用,還未能深刻使用,只能列舉目前能用到的示例代碼,自定義 Hooks,在我看來是對 Hooks 的組合封裝。

參考文章:

相關文章
相關標籤/搜索