React Hook

github的MD

hook

https://zh-hans.reactjs.org/docs/hooks-overview.html

Hook 是一些可以讓你在函數(shù)組件里“鉤入” React state 及生命周期等特性的函數(shù)赔硫。Hook 不能在 class 組件中使用 —— 這使得你不使用 class 也能使用 React。

Hook 使用規(guī)則

Hook 就是 JavaScript 函數(shù)跟继,但是使用它們會(huì)有兩個(gè)額外的規(guī)則:

  • 只能在函數(shù)最外層調(diào)用 Hook。不要在循環(huán)午阵、條件判斷或者子函數(shù)中調(diào)用解幽。
  • 只能在 React 的函數(shù)組件中調(diào)用 Hook。不要在其他 JavaScript 函數(shù)中調(diào)用戳葵。(還有一個(gè)地方可以調(diào)用 Hook —— 就是自定義的 Hook 中,我們稍后會(huì)學(xué)習(xí)到汉匙。)

linter 插件: https://www.npmjs.com/package/eslint-plugin-react-hooks

State Hook

import React, { useState } from 'react';

function Example() {
  // 聲明一個(gè)叫 "count" 的 state 變量
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

你可能想知道:為什么叫 useState 而不叫 createState?

“Create” 可能不是很準(zhǔn)確拱烁,因?yàn)?state 只在組件首次渲染的時(shí)候被創(chuàng)建。在下一次重新渲染時(shí)噩翠,useState 返回給我們當(dāng)前的 state戏自。否則它就不是 “state”了!這也是 Hook 的名字總是以 use 開頭的一個(gè)原因伤锚。我們將在后面的 Hook 規(guī)則中了解原因擅笔。

惰性初始 state

initialState 參數(shù)只會(huì)在組件的初始渲染中起作用,后續(xù)渲染時(shí)會(huì)被忽略。如果初始 state 需要通過復(fù)雜計(jì)算獲得猛们,則可以傳入一個(gè)函數(shù)念脯,在函數(shù)中計(jì)算并返回初始的 state,此函數(shù)只在初始渲染時(shí)被調(diào)用:

const [state, setState] = useState(() => {
  const initialState = someExpensiveComputation(props);
  return initialState;
});

Effect Hook

它給函數(shù)組件增加了操作副作用的能力弯淘。它跟 class 組件中的 componentDidMount绿店、componentDidUpdate 和 componentWillUnmount 具有相同的用途,只不過被合并成了一個(gè) API庐橙。

與 componentDidMount 或 componentDidUpdate 不同假勿,使用 useEffect 調(diào)度的 effect 不會(huì)阻塞瀏覽器更新屏幕,這讓你的應(yīng)用看起來響應(yīng)更快态鳖。大多數(shù)情況下转培,effect 不需要同步地執(zhí)行。在個(gè)別情況下(例如測(cè)量布局)郁惜,有單獨(dú)的 useLayoutEffect Hook 供你使用堡距,其 API 與 useEffect 相同甲锡。

import React, { useState, useEffect } from 'react';

function Example() {
 const [count, setCount] = useState(0);

 // 相當(dāng)于 componentDidMount 和 componentDidUpdate:
 useEffect(() => {
   // 使用瀏覽器的 API 更新頁面標(biāo)題
   document.title = `You clicked ${count} times`;
 });

 return (
   <div>
     <p>You clicked {count} times</p>
     <button onClick={() => setCount(count + 1)}>
       Click me
     </button>
   </div>
 );
}

當(dāng)你調(diào)用 useEffect 時(shí)兆蕉,就是在告訴 React 在完成對(duì) DOM 的更改后運(yùn)行你的“副作用”函數(shù)。由于副作用函數(shù)是在組件內(nèi)聲明的缤沦,所以它們可以訪問到組件的 props 和 state虎韵。默認(rèn)情況下,React 會(huì)在每次渲染后調(diào)用副作用函數(shù) —— 包括第一次渲染的時(shí)候缸废。

副作用函數(shù)還可以通過返回一個(gè)函數(shù)來指定如何“清除”副作用包蓝。例如,在下面的組件中使用副作用函數(shù)來訂閱好友的在線狀態(tài)企量,并通過取消訂閱來進(jìn)行清除操作:

import React, { useState, useEffect } from 'react';

function FriendStatus(props) {
  const [isOnline, setIsOnline] = useState(null);

  function handleStatusChange(status) {
    setIsOnline(status.isOnline);
  }

  useEffect(() => {
    ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
    return () => {
      ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
    };
  });

  if (isOnline === null) {
    return 'Loading...';
  }
  return isOnline ? 'Online' : 'Offline';
}

在這個(gè)示例中测萎,React 會(huì)在組件銷毀時(shí)取消對(duì) ChatAPI 的訂閱,然后在后續(xù)渲染時(shí)重新執(zhí)行副作用函數(shù)届巩。

跟 useState 一樣硅瞧,你可以在組件中多次使用 useEffect :

function FriendStatusWithCounter(props) {
  const [count, setCount] = useState(0);
  useEffect(() => {
    document.title = `You clicked ${count} times`;
  });

  const [isOnline, setIsOnline] = useState(null);
  useEffect(() => {
    ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
    return () => {
      ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
    };
  });

  function handleStatusChange(status) {
    setIsOnline(status.isOnline);
  }

通過跳過 Effect 進(jìn)行性能優(yōu)化

useEffect(() => {
  document.title = `You clicked ${count} times`;
}, [count]); // 僅在 count 更改時(shí)更新


useEffect(() => {
  function handleStatusChange(status) {
    setIsOnline(status.isOnline);
  }

  ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
  return () => {
    ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
  };
}, [props.friend.id]); // 僅在 props.friend.id 發(fā)生變化時(shí),重新訂閱

如果你要使用此優(yōu)化方式恕汇,請(qǐng)確保數(shù)組中包含了所有外部作用域中會(huì)隨時(shí)間變化并且在 effect 中使用的變量腕唧,否則你的代碼會(huì)引用到先前渲染中的舊變量。參閱文檔瘾英,了解更多關(guān)于如何處理函數(shù)以及數(shù)組頻繁變化時(shí)的措施內(nèi)容枣接。

如果想執(zhí)行只運(yùn)行一次的 effect(僅在組件掛載和卸載時(shí)執(zhí)行),可以傳遞一個(gè)空數(shù)組([])作為第二個(gè)參數(shù)缺谴。這就告訴 React 你的 effect 不依賴于 props 或 state 中的任何值但惶,所以它永遠(yuǎn)都不需要重復(fù)執(zhí)行。這并不屬于特殊情況 —— 它依然遵循依賴數(shù)組的工作方式。

如果你傳入了一個(gè)空數(shù)組([])膀曾,effect 內(nèi)部的 props 和 state 就會(huì)一直擁有其初始值片拍。盡管傳入 [] 作為第二個(gè)參數(shù)更接近大家更熟悉的 componentDidMount 和 componentWillUnmount 思維模式,但我們有更好的方式來避免過于頻繁的重復(fù)調(diào)用 effect妓肢。除此之外捌省,請(qǐng)記得 React 會(huì)等待瀏覽器完成畫面渲染之后才會(huì)延遲調(diào)用 useEffect,因此會(huì)使得額外操作很方便碉钠。

useContext

const value = useContext(MyContext);

接收一個(gè) context 對(duì)象(React.createContext 的返回值)并返回該 context 的當(dāng)前值纲缓。當(dāng)前的 context 值由上層組件中距離當(dāng)前組件最近的 <MyContext.Provider> 的 value prop 決定。

當(dāng)組件上層最近的 <MyContext.Provider> 更新時(shí)喊废,該 Hook 會(huì)觸發(fā)重渲染祝高,并使用最新傳遞給 MyContext provider 的 context value 值畜埋。即使祖先使用 React.memo 或 shouldComponentUpdate迫肖,也會(huì)在組件本身使用 useContext 時(shí)重新渲染渗磅。

const themes = {
  light: {
    foreground: "#000000",
    background: "#eeeeee"
  },
  dark: {
    foreground: "#ffffff",
    background: "#222222"
  }
};

const ThemeContext = React.createContext(themes.light);

function App() {
  return (
    <ThemeContext.Provider value={themes.dark}>
      <Toolbar />
    </ThemeContext.Provider>
  );
}

function Toolbar(props) {
  return (
    <div>
      <ThemedButton />
    </div>
  );
}

function ThemedButton() {
  const theme = useContext(ThemeContext);
  return (
    <button style={{ background: theme.background, color: theme.foreground }}>
      I am styled by theme context!
    </button>
  );
}

useReducer

用 reducer 重寫 useState 一節(jié)的計(jì)數(shù)器示例:

const initialState = {count: 0};

function reducer(state, action) {
  switch (action.type) {
    case 'increment':
      return {count: state.count + 1};
    case 'decrement':
      return {count: state.count - 1};
    default:
      throw new Error();
  }
}

function Counter() {
  const [state, dispatch] = useReducer(reducer, initialState);
  return (
    <>
      Count: {state.count}
      <button onClick={() => dispatch({type: 'decrement'})}>-</button>
      <button onClick={() => dispatch({type: 'increment'})}>+</button>
    </>
  );
}

惰性初始化

你可以選擇惰性地創(chuàng)建初始 state师脂。為此牺汤,需要將 init 函數(shù)作為 useReducer 的第三個(gè)參數(shù)傳入竣付,這樣初始 state 將被設(shè)置為 init(initialArg)寇窑。

這么做可以將用于計(jì)算 state 的邏輯提取到 reducer 外部凤藏,這也為將來對(duì)重置 state 的 action 做處理提供了便利:

function init(initialCount) {
  return {count: initialCount};
}

function reducer(state, action) {
  switch (action.type) {
    case 'increment':
      return {count: state.count + 1};
    case 'decrement':
      return {count: state.count - 1};
    case 'reset':
      return init(action.payload);
    default:
      throw new Error();
  }
}

function Counter({initialCount}) {
  const [state, dispatch] = useReducer(reducer, initialCount, init);
  return (
    <>
      Count: {state.count}
      <button
        onClick={() => dispatch({type: 'reset', payload: initialCount})}>
        Reset
      </button>
      <button onClick={() => dispatch({type: 'decrement'})}>-</button>
      <button onClick={() => dispatch({type: 'increment'})}>+</button>
    </>
  );
}

useCallback

把內(nèi)聯(lián)回調(diào)函數(shù)及依賴項(xiàng)數(shù)組作為參數(shù)傳入 useCallback惋增,它將返回該回調(diào)函數(shù)的 memoized 版本叠殷,該回調(diào)函數(shù)僅在某個(gè)依賴項(xiàng)改變時(shí)才會(huì)更新。

const memoizedCallback = useCallback(
  () => {
    doSomething(a, b);
  },
  [a, b],
);

useCallback(fn, deps) 相當(dāng)于 useMemo(() => fn, deps)诈皿。

useMemo

const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);

如果沒有提供依賴項(xiàng)數(shù)組林束,useMemo 在每次渲染時(shí)都會(huì)計(jì)算新的值。

你可以把 useMemo 作為性能優(yōu)化的手段稽亏,但不要把它當(dāng)成語義上的保證壶冒。將來,React 可能會(huì)選擇“遺忘”以前的一些 memoized 值截歉,并在下次渲染時(shí)重新計(jì)算它們胖腾,比如為離屏組件釋放內(nèi)存。先編寫在沒有 useMemo 的情況下也可以執(zhí)行的代碼 —— 之后再在你的代碼中添加 useMemo怎披,以達(dá)到優(yōu)化性能的目的胸嘁。

useRef

它創(chuàng)建的是一個(gè)普通 Javascript 對(duì)象。而 useRef() 和自建一個(gè) {current: ...} 對(duì)象的唯一區(qū)別是凉逛,useRef 會(huì)在每次渲染時(shí)返回同一個(gè) ref 對(duì)象性宏。

請(qǐng)記住,當(dāng) ref 對(duì)象內(nèi)容發(fā)生變化時(shí)状飞,useRef 并不會(huì)通知你毫胜。變更 .current 屬性不會(huì)引發(fā)組件重新渲染书斜。如果想要在 React 綁定或解綁 DOM 節(jié)點(diǎn)的 ref 時(shí)運(yùn)行某些代碼,則需要使用回調(diào) ref 來實(shí)現(xiàn)酵使。

function TextInputWithFocusButton() {
  const inputEl = useRef(null);
  const onButtonClick = () => {
    // `current` 指向已掛載到 DOM 上的文本輸入元素
    inputEl.current.focus();
  };
  return (
    <>
      <input ref={inputEl} type="text" />
      <button onClick={onButtonClick}>Focus the input</button>
    </>
  );
}

自定義 Hook

自定義 Hook 更像是一種約定而不是功能荐吉。如果函數(shù)的名字以 “use” 開頭并調(diào)用其他 Hook,我們就說這是一個(gè)自定義 Hook口渔。 useSomething 的命名約定可以讓我們的 linter 插件在使用 Hook 的代碼中找到 bug样屠。

前面,我們介紹了一個(gè)叫 FriendStatus 的組件缺脉,它通過調(diào)用 useState 和 useEffect 的 Hook 來訂閱一個(gè)好友的在線狀態(tài)痪欲。假設(shè)我們想在另一個(gè)組件里重用這個(gè)訂閱邏輯。
首先攻礼,我們把這個(gè)邏輯抽取到一個(gè)叫做 useFriendStatus 的自定義 Hook 里:

import React, { useState, useEffect } from 'react';

function useFriendStatus(friendID) {
  const [isOnline, setIsOnline] = useState(null);

  function handleStatusChange(status) {
    setIsOnline(status.isOnline);
  }

  useEffect(() => {
    ChatAPI.subscribeToFriendStatus(friendID, handleStatusChange);
    return () => {
      ChatAPI.unsubscribeFromFriendStatus(friendID, handleStatusChange);
    };
  });

  return isOnline;
}

使用

function FriendStatus(props) {
  const isOnline = useFriendStatus(props.friend.id);

  if (isOnline === null) {
    return 'Loading...';
  }
  return isOnline ? 'Online' : 'Offline';
}
function FriendListItem(props) {
  const isOnline = useFriendStatus(props.friend.id);

  return (
    <li style={{ color: isOnline ? 'green' : 'black' }}>
      {props.friend.name}
    </li>
  );
}

每個(gè)組件間的 state 是完全獨(dú)立的业踢。Hook 是一種復(fù)用狀態(tài)邏輯的方式,它不復(fù)用 state 本身礁扮。事實(shí)上 Hook 的每次調(diào)用都有一個(gè)完全獨(dú)立的 state —— 因此你可以在單個(gè)組件中多次調(diào)用同一個(gè)自定義 Hook知举。

useImperativeHandle

useImperativeHandle 可以讓你在使用 ref 時(shí)自定義暴露給父組件的實(shí)例值。在大多數(shù)情況下太伊,應(yīng)當(dāng)避免使用 ref 這樣的命令式代碼雇锡。useImperativeHandle 應(yīng)當(dāng)與 forwardRef 一起使用:

function FancyInput(props, ref) {
  const inputRef = useRef();
  useImperativeHandle(ref, () => ({
    focus: () => {
      inputRef.current.focus();
    }
  }));
  return <input ref={inputRef} ... />;
}
FancyInput = forwardRef(FancyInput);

<!--使用-->
const App = props => {
  const fancyInputRef = useRef();
  return (
    <div>
      <FancyInput ref={fancyInputRef} />
      <button
        onClick={() => fancyInputRef.current.focus()}
      >父組件調(diào)用子組件的 focus</button>
    </div>
  )
}

在本例中,渲染 <FancyInput ref={inputRef} /> 的父組件可以調(diào)用 inputRef.current.focus()倦畅。

useLayoutEffect

其函數(shù)簽名與 useEffect 相同遮糖,但它會(huì)在所有的 DOM 變更之后同步調(diào)用 effect〉停可以使用它來讀取 DOM 布局并同步觸發(fā)重渲染。在瀏覽器執(zhí)行繪制之前屡江,useLayoutEffect 內(nèi)部的更新計(jì)劃將被同步刷新芭概。

盡可能使用標(biāo)準(zhǔn)的 useEffect 以避免阻塞視覺更新。

useDebugValue

useDebugValue 可用于在 React 開發(fā)者工具中顯示自定義 hook 的標(biāo)簽惩嘉。

例如罢洲,“自定義 Hook” 章節(jié)中描述的名為 useFriendStatus 的自定義 Hook:

function useFriendStatus(friendID) {
  const [isOnline, setIsOnline] = useState(null);

  // ...

  // 在開發(fā)者工具中的這個(gè) Hook 旁邊顯示標(biāo)簽
  // e.g. "FriendStatus: Online"
  useDebugValue(isOnline ? 'Online' : 'Offline');

  return isOnline;
}

tips:
我們不推薦你向每個(gè)自定義 Hook 添加 debug 值。當(dāng)它作為共享庫的一部分時(shí)才最有價(jià)值文黎。

延遲格式化 debug 值

在某些情況下惹苗,格式化值的顯示可能是一項(xiàng)開銷很大的操作。除非需要檢查 Hook耸峭,否則沒有必要這么做桩蓉。

因此,useDebugValue 接受一個(gè)格式化函數(shù)作為可選的第二個(gè)參數(shù)劳闹。該函數(shù)只有在 Hook 被檢查時(shí)才會(huì)被調(diào)用院究。它接受 debug 值作為參數(shù)洽瞬,并且會(huì)返回一個(gè)格式化的顯示值。

例如业汰,一個(gè)返回 Date 值的自定義 Hook 可以通過格式化函數(shù)來避免不必要的 toDateString 函數(shù)調(diào)用:

useDebugValue(date, date => date.toDateString());

Tips:

如何避免向下傳遞回調(diào)伙窃?

我們已經(jīng)發(fā)現(xiàn)大部分人并不喜歡在組件樹的每一層手動(dòng)傳遞回調(diào)。盡管這種寫法更明確样漆,但這給人感覺像錯(cuò)綜復(fù)雜的管道工程一樣麻煩为障。

在大型的組件樹中,我們推薦的替代方案是通過 context 用 useReducer 往下傳一個(gè) dispatch 函數(shù)

const TodosDispatch = React.createContext(null);

function TodosApp() {
  // 提示:`dispatch` 不會(huì)在重新渲染之間變化
  const [todos, dispatch] = useReducer(todosReducer);

  return (
    <TodosDispatch.Provider value={dispatch}>
      <DeepTree todos={todos} />
    </TodosDispatch.Provider>
  );
}
function DeepChild(props) {
  // 如果我們想要執(zhí)行一個(gè) action放祟,我們可以從 context 中獲取 dispatch产场。
  const dispatch = useContext(TodosDispatch);

  function handleClick() {
    dispatch({ type: 'add', text: 'hello' });
  }

  return (
    <button onClick={handleClick}>Add todo</button>
  );
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市舞竿,隨后出現(xiàn)的幾起案子京景,更是在濱河造成了極大的恐慌,老刑警劉巖骗奖,帶你破解...
    沈念sama閱讀 217,542評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件确徙,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡执桌,警方通過查閱死者的電腦和手機(jī)鄙皇,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來仰挣,“玉大人伴逸,你說我怎么就攤上這事”旌” “怎么了错蝴?”我有些...
    開封第一講書人閱讀 163,912評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)颓芭。 經(jīng)常有香客問我顷锰,道長(zhǎng),這世上最難降的妖魔是什么亡问? 我笑而不...
    開封第一講書人閱讀 58,449評(píng)論 1 293
  • 正文 為了忘掉前任官紫,我火速辦了婚禮,結(jié)果婚禮上州藕,老公的妹妹穿的比我還像新娘束世。我一直安慰自己,他們只是感情好床玻,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,500評(píng)論 6 392
  • 文/花漫 我一把揭開白布毁涉。 她就那樣靜靜地躺著,像睡著了一般笨枯。 火紅的嫁衣襯著肌膚如雪薪丁。 梳的紋絲不亂的頭發(fā)上遇西,一...
    開封第一講書人閱讀 51,370評(píng)論 1 302
  • 那天,我揣著相機(jī)與錄音严嗜,去河邊找鬼粱檀。 笑死,一個(gè)胖子當(dāng)著我的面吹牛漫玄,可吹牛的內(nèi)容都是我干的茄蚯。 我是一名探鬼主播,決...
    沈念sama閱讀 40,193評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼睦优,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼渗常!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起汗盘,我...
    開封第一講書人閱讀 39,074評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤皱碘,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后隐孽,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體癌椿,經(jīng)...
    沈念sama閱讀 45,505評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,722評(píng)論 3 335
  • 正文 我和宋清朗相戀三年菱阵,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了踢俄。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,841評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡晴及,死狀恐怖都办,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情虑稼,我是刑警寧澤琳钉,帶...
    沈念sama閱讀 35,569評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站动雹,受9級(jí)特大地震影響槽卫,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜胰蝠,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,168評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望震蒋。 院中可真熱鬧茸塞,春花似錦、人聲如沸查剖。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽笋庄。三九已至效扫,卻和暖如春倔监,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背菌仁。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工浩习, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人济丘。 一個(gè)月前我還...
    沈念sama閱讀 47,962評(píng)論 2 370
  • 正文 我出身青樓谱秽,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親摹迷。 傳聞我的和親對(duì)象是個(gè)殘疾皇子疟赊,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,781評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • 主要介紹 useState useEffect useReducer useContext 用法 你還在為...
    叫我蘇軾好嗎閱讀 27,410評(píng)論 3 41
  • 首先,讓我們談?wù)勈裁词莚eact hook峡碉。先剖出官方解釋: Hook 是 React 16.8 的新增特性近哟。它可...
    趣談前端_徐小夕閱讀 25,050評(píng)論 0 17
  • 什么是React Hook? 一個(gè)特殊的函數(shù),用于鉤入React的特性鲫寄。它鼓勵(lì)我們將通用邏輯封裝成Hook而不是工...
    南山碼僧閱讀 622評(píng)論 0 7
  • Hook 是 react 16.8 推出的新特性吉执,具有如下優(yōu)點(diǎn):Hook 使你在無需修改組件結(jié)構(gòu)的情況下復(fù)用狀態(tài)邏...
    林木木road閱讀 789評(píng)論 0 1
  • 現(xiàn)在編寫新的組件的時(shí)候我們有兩個(gè)選擇:class組件和函數(shù)組件。那么什么是函數(shù)組件呢塔拳? 現(xiàn)在來看一段函數(shù): 可以看...
    arial_1df2閱讀 352評(píng)論 0 0