您好,登錄后才能下訂單哦!
小編給大家分享一下react hooks有什么用,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
React hooks是React16.8的新特性,可以讓React函數組件具有狀態,并提供類似componentDidMount和componentDidUpdate等生命周期方法。
我們大部分 React 類組件可以保存狀態,而函數組件不能? 并且類組件具有生命周期,而函數組件卻不能?
React 早期版本,類組件可以通過繼承PureComponent來優化一些不必要的渲染,相對于函數組件,React 官網沒有提供對應的方法來緩存函數組件以減少一些不必要的渲染,直接 16.6 出來的 React.memo函數。
React 16.8 新出來的Hooks可以讓React 函數組件具有狀態,并提供類似 componentDidMount和componentDidUpdate等生命周期方法。
Hook 這個單詞的意思是"鉤子"。
React Hooks 的意思是,組件盡量寫成純函數,如果需要外部功能和副作用,就用鉤子把外部代碼"鉤"進來。 React Hooks 就是那些鉤子。
你需要什么功能,就使用什么鉤子。React 默認提供了一些常用鉤子,你也可以封裝自己的鉤子。
所有的鉤子都是為函數引入外部功能,所以 React 約定,鉤子一律使用use前綴命名,便于識別。你要使用 xxx 功能,鉤子就命名為 usexxx。
下面介紹 React 默認提供的四個最常用的鉤子。
useState()
useContext()
useReducer()
useEffect()
useState():狀態鉤子
useState()用于為函數組件引入狀態(state)。純函數不能有狀態,所以把狀態放在鉤子里面。
本文前面那個組件類,用戶點擊按鈕,會導致按鈕的文字改變,文字取決于用戶是否點擊,這就是狀態。使用useState()重寫如下。
import React, { useState } from "react"; export default function Button() { const [buttonText, setButtonText] = useState("Click me, please"); function handleClick() { return setButtonText("Thanks, been clicked!"); } return <button onClick={handleClick}>{buttonText}</button>; }
demo地址:https://codesandbox.io/s/nifty-waterfall-4i2dq
上面代碼中,Button 組件是一個函數,內部使用useState()鉤子引入狀態。
useState()這個函數接受狀態的初始值,作為參數,上例的初始值為按鈕的文字。該函數返回一個數組,數組的第一個成員是一個變量(上例是buttonText),指向狀態的當前值。第二個成員是一個函數,用來更新狀態,約定是set前綴加上狀態的變量名(上例是setButtonText)。
useContext():共享狀態鉤子
如果需要在組件之間共享狀態,可以使用useContext()。
現在有兩個組件 Navbar 和 Messages,我們希望它們之間共享狀態。
<div className="App"> <Navbar/> <Messages/> </div>
第一步就是使用 React Context API,在組件外部建立一個 Context。
const AppContext = React.createContext({});
組件封裝代碼如下。
<AppContext.Provider value={{ username: 'superawesome' }}> <div className="App"> <Navbar/> <Messages/> </div> </AppContext.Provider>
上面代碼中,AppContext.Provider提供了一個 Context 對象,這個對象可以被子組件共享。
Navbar 組件的代碼如下。
const Navbar = () => { const { username } = useContext(AppContext); return ( <div className="navbar"> <p>AwesomeSite</p> <p>{username}</p> </div> ); }
上面代碼中,useContext()鉤子函數用來引入 Context 對象,從中獲取username屬性。
Message 組件的代碼也類似。
const Messages = () => { const { username } = useContext(AppContext) return ( <div className="messages"> <h2>Messages</h2> <p>1 message for {username}</p> <p className="message">useContext is awesome!</p> </div> ) }
demo:https://codesandbox.io/s/react-usecontext-redux-0bj1v
useReducer():action 鉤子
React 本身不提供狀態管理功能,通常需要使用外部庫。這方面最常用的庫是 Redux。
Redux 的核心概念是,組件發出 action 與狀態管理器通信。狀態管理器收到 action 以后,使用 Reducer 函數算出新的狀態,Reducer 函數的形式是(state, action) => newState。
useReducers()鉤子用來引入 Reducer 功能。
const [state, dispatch] = useReducer(reducer, initialState);
上面是useReducer()的基本用法,它接受 Reducer 函數和狀態的初始值作為參數,返回一個數組。數組的第一個成員是狀態的當前值,第二個成員是發送 action 的dispatch函數。
下面是一個計數器的例子。用于計算狀態的 Reducer 函數如下。
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> ); }
demo:https://codesandbox.io/s/react-usereducer-redux-xqlet
由于 Hooks 可以提供共享狀態和 Reducer 函數,所以它在這些方面可以取代 Redux。但是,它沒法提供中間件(middleware)和時間旅行(time travel),如果你需要這兩個功能,還是要用 Redux。
useEffect():副作用鉤子
useEffect()用來引入具有副作用的操作,最常見的就是向服務器請求數據。以前,放在componentDidMount里面的代碼,現在可以放在useEffect()。
useEffect()的用法如下。
useEffect(() => { // Async Action }, [dependencies])
上面用法中,useEffect()接受兩個參數。第一個參數是一個函數,異步操作的代碼放在里面。第二個參數是一個數組,用于給出 Effect 的依賴項,只要這個數組發生變化,useEffect()就會執行。第二個參數可以省略,這時每次組件渲染時,就會執行useEffect()。
下面看一個例子。
const Person = ({ personId }) => { const [loading, setLoading] = useState(true); const [person, setPerson] = useState({}); useEffect(() => { setLoading(true); fetch(`https://swapi.co/api/people/${personId}/`) .then(response => response.json()) .then(data => { setPerson(data); setLoading(false); }); }, [personId]) if (loading === true) { return <p>Loading ...</p> } return <div> <p>You're viewing: {person.name}</p> <p>Height: {person.height}</p> <p>Mass: {person.mass}</p> </div> }
上面代碼中,每當組件參數personId發生變化,useEffect()就會執行。組件第一次渲染時,useEffect()也會執行。
demo:https://codesandbox.io/s/react-useeffect-redux-9t3bg
創建自己的 Hooks
上例的 Hooks 代碼還可以封裝起來,變成一個自定義的 Hook,便于共享。
const usePerson = (personId) => { const [loading, setLoading] = useState(true); const [person, setPerson] = useState({}); useEffect(() => { setLoading(true); fetch(`https://swapi.co/api/people/${personId}/`) .then(response => response.json()) .then(data => { setPerson(data); setLoading(false); }); }, [personId]); return [loading, person]; };
上面代碼中,usePerson()就是一個自定義的 Hook。
Person 組件就改用這個新的鉤子,引入封裝的邏輯。
const Person = ({ personId }) => { const [loading, person] = usePerson(personId); if (loading === true) { return <p>Loading ...</p>; } return ( <div> <p>You're viewing: {person.name}</p> <p>Height: {person.height}</p> <p>Mass: {person.mass}</p> </div> ); };
demo:https://codesandbox.io/s/react-useeffect-redux-ghl7c
以上是“react hooks有什么用”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。