您好,登錄后才能下訂單哦!
本篇文章給大家分享的是有關(guān)React中10種Hook的使用方法,小編覺得挺實用的,因此分享給大家學習,希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。
React官網(wǎng)是這么介紹的: Hook 是 React 16.8 的新增特性。它可以讓你在不編寫 class 的情況下使用 state 以及其他的 React 特性。
完全可選的 你無需重寫任何已有代碼就可以在一些組件中嘗試 Hook。但是如果你不想,你不必現(xiàn)在就去學習或使用 Hook。
100% 向后兼容的 Hook 不包含任何破壞性改動。
現(xiàn)在可用 Hook 已發(fā)布于 v16.8.0。
沒有計劃從 React 中移除 class 你可以在本頁底部的章節(jié)讀到更多關(guān)于 Hook 的漸進策略。
Hook 不會影響你對 React 概念的理解 恰恰相反,Hook 為已知的 React 概念提供了更直接的 API:props, state,context,refs 以及生命周期。稍后我們將看到,Hook 還提供了一種更強大的方式來組合他們。
如果對react還不夠了解建議先看下react官方文檔,寫寫demo再來看文章,因為有的react基礎(chǔ)的東西我就一筆帶過不細說。
react 官方文檔 https://zh-hans.reactjs.org/docs/hooks-state.html
hook | 用途 |
---|---|
useState | 設(shè)置和改變state,代替原來的state和setState |
useEffect | 代替原來的生命周期,componentDidMount,componentDidUpdate 和 componentWillUnmount 的合并版 |
useLayoutEffect | 與 useEffect 作用相同,但它會同步調(diào)用 effect |
useMemo | 控制組件更新條件,可根據(jù)狀態(tài)變化控制方法執(zhí)行,優(yōu)化傳值 |
useCallback | useMemo優(yōu)化傳值,usecallback優(yōu)化傳的方法,是否更新 |
useRef | 跟以前的ref,一樣,只是更簡潔了 |
useContext | 上下文爺孫及更深組件傳值 |
useReducer | 代替原來redux里的reducer,配合useContext一起使用 |
useDebugValue | 在 React 開發(fā)者工具中顯示自定義 hook 的標簽,調(diào)試使用。 |
useImperativeHandle | 可以讓你在使用 ref 時自定義暴露給父組件的實例值。 |
import React from 'react'; import './App.css'; //通常的class寫法,改變狀態(tài) class App extends React.Component { constructor(props){ super(props) this.state = { hook:'react hook 是真的好用啊' } } changehook = () => { this.setState({ hook:'我改變了react hook 的值' }) } render () { const { hook } = this.state return( <header className="App-header"> {hook} <button onClick={this.changehook}> 改變hook </button> </header> ) } } export {App} //函數(shù)式寫法,改變狀態(tài) function App() { //創(chuàng)建了一個叫hook的變量,sethook方法可以改變這個變量,初始值為‘react hook 是真的好用啊' const [hook, sethook] = useState("react hook 是真的好用啊"); return ( <header className="App-header"> {hook}{/**這里的變量和方法也是可以直接使用的 */} <button onClick={() => sethook("我改變了react hook 的值")}> 改變hook </button> </header> ); } export {App} //箭頭函數(shù)的函數(shù)寫法,改變狀態(tài) export const App = props => { const [hook, sethook] = useState("react hook 是真的好用啊"); return ( <header className="App-header"> {hook} <button onClick={() => sethook("我改變了react hook 的值")}> 改變hook </button> </header> ); };
使用方法備注在上面的demo中
看完上面useState的對比使用,一個小的demo結(jié)構(gòu)更清晰,代碼更簡潔,更像寫js代碼,運用到項目中,那豈不是美滋滋。
useEffect代替原來的生命周期,componentDidMount,componentDidUpdate 和 componentWillUnmount 的合并版
useEffect( ()=>{ return ()=>{ } } , [ ])
第一個參數(shù),是函數(shù),默認第一次渲染和更新時都會觸發(fā),默認自帶一個return ,return一個函數(shù)表示可以再銷毀之前可以處理些事情
第二個參數(shù),數(shù)組【】,空的時候表示只執(zhí)行一次,更新時不觸發(fā),里面的參數(shù)是什么,當參數(shù)變化時才會執(zhí)行useEffect
useEffect可以多次使用,按照先后順序執(zhí)行
useLayoutEffect 強制useeffect的執(zhí)行為同步,并且先執(zhí)行useLayoutEffect內(nèi)部的函數(shù)
import React, { useState, useEffect, useLayoutEffect } from 'react'; //箭頭函數(shù)的寫法,改變狀態(tài) const UseEffect = (props) => { //創(chuàng)建了一個叫hook的變量,sethook方法可以改變這個變量,初始值為‘react hook 是真的好用啊' const [ hook, sethook ] = useState('react hook 是真的好用啊'); const [ name ] = useState('baby張'); return ( <header className="UseEffect-header"> <h4>UseEffect</h4> <Child hook={hook} name={name} /> {/**上面的變量和下面方法也是可以直接使用的 */} <button onClick={() => sethook('我改變了react hook 的值' + new Date().getTime())}>改變hook</button> </header> ); }; const Child = (props) => { const [ newhook, setnewhook ] = useState(props.hook); //這樣寫可以代替以前的componentDidMount,第二個參數(shù)為空數(shù)組,表示該useEffect只執(zhí)行一次 useEffect(() => { console.log('first componentDidMount'); }, []); //第二個參數(shù),數(shù)組里是hook,當hook變化時,useEffect會觸發(fā),當hook變化時,先銷毀再執(zhí)行第一個函數(shù)。 useEffect( () => { setnewhook(props.hook + '222222222'); console.log('useEffect'); return () => { console.log('componentWillUnmount '); }; }, [ props.hook ] ); //useLayoutEffect 強制useeffect的執(zhí)行為同步,并且先執(zhí)行useLayoutEffect內(nèi)部的函數(shù) useLayoutEffect( () => { console.log('useLayoutEffect'); return () => { console.log('useLayoutEffect componentWillUnmount'); }; }, [ props.hook ] ); return ( <div> <p>{props.name}</p> {newhook} </div> ); }; export default UseEffect;
他們都可以用來優(yōu)化子組件的渲染問題,或者監(jiān)聽子組件狀態(tài)變化來處理事件,這一點在以前是很難做到的,因為shouldComponentUpdate 里能監(jiān)聽到是否變化,但沒法控制其他的外部方法,只能返回true和false,而componentDidUpdate只能在更新后執(zhí)行,所以想在渲染之前做些事情就不好搞了。
useCallback目前還不能用
import React, { useState, useMemo } from 'react'; const Child = ({ age, name, children }) => { //在不用useMemo做處理的時候,只要父組件狀態(tài)改變了,子組件都會渲染一次,用了useMemo可以監(jiān)聽某個狀態(tài)name,當name變化時候執(zhí)行useMemo里第一個函數(shù) console.log(age, name, children, '11111111'); function namechange() { console.log(age, name, children, '22222222'); return name + 'change'; } {/** react 官網(wǎng)雖說useCallback與useMemo的功能差不多,但不知道版本問題還怎么回是,這個方法目前還不能用 const memoizedCallback = useCallback( () => { console.log('useCallback') }, [name], ); console.log(memoizedCallback,'memoizedCallback') */} //useMemo有兩個參數(shù),和useEffect一樣,第一個參數(shù)是函數(shù),第二個參數(shù)是個數(shù)組,用來監(jiān)聽某個狀態(tài)不變化 const changedname = useMemo(() => namechange(), [ name ]); return ( <div style={{ border: '1px solid' }}> <p>children:{children}</p> <p>name:{name}</p> <p>changed:{changedname}</p> <p>age:{age}</p> </div> ); }; const UseMemo = () => { //useState 設(shè)置名字和年齡,并用2兩個按鈕改變他們,傳給Child組件 const [ name, setname ] = useState('baby張'); const [ age, setage ] = useState(18); return ( <div> <button onClick={() => { setname('baby張' + new Date().getTime()); }} > 改名字 </button> <button onClick={() => { setage('年齡' + new Date().getTime()); }} > 改年齡 </button> <p> UseMemo {name}:{age} </p> <Child age={age} name={name}> {name}的children </Child> </div> ); }; export default UseMemo;
ref跟之前差不多,useRef創(chuàng)建–綁定–使用,三步走,詳細看代碼以及備注
import React, { useState, useRef } from 'react'; const UseRef = () => { //這里useState綁定個input,關(guān)聯(lián)一個狀態(tài)name const [ name, setname ] = useState('baby張'); const refvalue = useRef(null);// 先創(chuàng)建一個空的useRef function addRef() { refvalue.current.value = name; //點擊按鈕時候給這個ref賦值 // refvalue.current = name //這樣寫時,即使ref沒有綁定在dom上,值依然會存在創(chuàng)建的ref上,并且可以使用它 console.log(refvalue.current.value); } return ( <div> <input defaultValue={name} onChange={(e) => { setname(e.target.value); }} /> <button onClick={addRef}>給下面插入名字</button> <p>給我個UseRef名字:</p> <input ref={refvalue} /> </div> ); }; export default UseRef;
之前使用過context的小伙伴一看就懂,useContext的話跟之前的context基本用法差不多,代碼內(nèi)有詳細注釋說明,創(chuàng)建,傳值,使用
import React, { useState, useContext, createContext } from 'react'; const ContextName = createContext(); //這里為了方便寫博客,爺爺孫子組件都寫在一個文件里,正常需要在爺爺組件和孫子組件挨個引入創(chuàng)建的Context const UseContext = () => { //這里useState創(chuàng)建一個狀態(tài),并按鈕控制變化 const [ name, setname ] = useState('baby張'); return ( <div> <h4>UseContext 爺爺</h4> <button onClick={() => { setname('baby張' + new Date().getTime()); }} > 改變名字 </button> {/**這里跟context用法一樣,需要provider向子組件傳遞value值,value不一定是一個參數(shù) */}} <ContextName.Provider value={{ name: name, age: 18 }}> {/**需要用到變量的子組件一定要寫在provider中間,才能實現(xiàn)共享 */} <Child /> </ContextName.Provider> </div> ); }; const Child = () => { //創(chuàng)建一個兒子組件,里面引入孫子組件 return ( <div style={{ border: '1px solid' }}> Child 兒子 <ChildChild /> </div> ); }; const ChildChild = () => { //創(chuàng)建孫子組件,接受爺爺組件的狀態(tài),用useContext,獲取到爺爺組件創(chuàng)建的ContextName的value值 let childname = useContext(ContextName); return ( <div style={{ border: '1px solid' }}> ChildChild 孫子 <p> {childname.name}:{childname.age} </p> </div> ); }; export default UseContext;
這里的usereducer會返回state和dispatch,通過context傳遞到子組件,然后直接調(diào)用state或者觸發(fā)reducer,我們常用useReducer 與useContext createContext一起用,模擬reudx的傳值和重新賦值操作。
import React, { useState, useReducer, useContext, createContext } from 'react'; //初始化stroe的類型、初始化值、創(chuàng)建reducer const ADD_COUNTER = 'ADD_COUNTER'; const initReducer = { count: 0 }; //正常的reducer編寫 function reducer(state, action) { switch (action.type) { case ADD_COUNTER: return { ...state, count: state.count + 1 }; default: return state; } } const CountContext = createContext(); //上面這一段,初始化state和reducer創(chuàng)建context,可以單獨寫一個文件,這里為了方便理解,放一個文件里寫了 const UseReducer = () => { const [ name, setname ] = useState('baby張'); //父組件里使用useReducer,第一個參數(shù)是reducer函數(shù),第二個參數(shù)是state,返回的是state和dispash const [ state, dispatch ] = useReducer(reducer, initReducer); return ( <div> UseReducer {/* 在這里通過context,講reducer和state傳遞給子組件*/} <CountContext.Provider value={{ state, dispatch, name, setname }}> <Child /> </CountContext.Provider> </div> ); }; const Child = () => { //跟正常的接受context一樣,接受父組件的值,通過事件等方式觸發(fā)reducer,實現(xiàn)redux效果 const { state, dispatch, name, setname } = useContext(CountContext); function handleclick(count) { dispatch({ type: ADD_COUNTER, count: 17 }); setname(count % 2 == 0 ? 'babybrother' : 'baby張'); } return ( <div> <p> {name}今年{state.count}歲 </p> <button onClick={() => handleclick(state.count)}>長大了</button> </div> ); }; export default UseReducer;
附上github地址 10個hook demo 點一點star,
以上就是React中10種Hook的使用方法,小編相信有部分知識點可能是我們?nèi)粘9ぷ鲿姷交蛴玫降摹OM隳芡ㄟ^這篇文章學到更多知識。更多詳情敬請關(guān)注億速云行業(yè)資訊頻道。
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。