React Hook(鉤子)

react hook?官網地址https://react.docschina.org/docs/hooks-intro.html

函數式組件:

const? App=()=>{? ?renturn (? ?<div><div/>)? }??

函數式組件特點:1.沒有state放數據? 2.沒有生命周期 3.沒有this指向問題

hook主要是服務于函數是組件的,常用的hook有:

1.useState

import?{?useState?}?from?'react'

function?App1()?{

????//?const?[變量名,?修改變量的方法]?=?useState(變量的初始值)

????const?[num,?setNum]?=?useState(0)

????function?btnClick(){

????????//?setNum的作用是將最新的一個值賦值給num

????????setNum(num+1)

????}

????return?(

????????<div>

????????????<h1>{num}</h1>

????????????<button?onClick={btnClick}>累加</button>

????????</div>

????)

}

export?default?App1;

2.useEffect(相當于三個生命周期 componentDidMount?+?componentDidUpdate?+?componentWillUnmount useEffect可以檢測數據更新 )

useEffect(callback,Array)有兩個參數? 如果Array的[]代表不檢測任何數據

?/useEffect包含了三個聲明周期??其中一個是銷毀的生命周期??第二參數不寫的時候只檢測return里面銷毀的的數據?如果寫第二個參就不要寫return? ? ?import?{? useEffect?}?from?'react'

? (函數式組件中寫下面這一段)

? ?useEffect(()?=>?{

????????console.log('數據更新了');

????????return?()?=>?{

????????????console.log('組件銷毀了');

????????}

????},?[])


3.useContext 和createContext(使用上下文和創建上下文)

import?React?from?'react'

//?引入這三個hook

import?{?useState,?createContext,?useContext?}?from?'react'

//創建上下文

const?NumContext?=?createContext()

//?創建子組件

function?Child()?{

????//?使用上下文

????const?num?=?useContext(NumContext)

????//?console.log(useContext(NumContext));

????return?<h1>{num}</h1>

}

export?default?function?App1()?{

????const?[num,?setNum]?=?useState(100)

????return?(

????????<div>

????????????<NumContext.Provider?value={num}>

????????????????<Child?/>

????????????</NumContext.Provider>

????????????<button?onClick={()?=>?setNum(num?+?1)}>累加</button>

????????</div>

????)

}//全局創建上下文(const?NumContext?=?createContext()) ==>全局上下文父組件中包裹子組件(???<NumContext.Provider?value={num}>? ? ?<Child?/>??</NumContext.Provider> 提供器傳遞參數必須是value)==>子組件使用上下文(??const?num?=?useContext(NumContext)? 標簽內使用?<h1>{num}</h1>)


3.1createContext(使用上下文和創建上下文)

import?React?from?'react'

import?{?useState,?createContext?}?from?'react'

const?NumContext?=?createContext()

function?Child()?{

????return?(

????????<NumContext.Consumer>

????????????{

????????????????num?=>?<h1>{num}</h1>

????????????}

????????</NumContext.Consumer>

????)

}

function?App2()?{

????const?[num,?setNum]?=?useState(0)

????return?(

????????<div>

????????????{/*?相當于react-redux里面的提供器?*/}

????????????<NumContext.Provider?value={num}>

????????????????<Child?/>

????????????</NumContext.Provider>

????????????<button?onClick={()?=>?setNum(num?+?1)}>累加</button>

????????</div>

????)

}//提供器傳遞參數(Provider?)===>消費器使用(Consumer? 函數的形式使用)

export?default?App2

4.useReducer(useReducer結合usecontext實現redux)

import?React?from?'react'

//?引入這三個hook

import?{?createContext,?useContext,?useReducer?}?from?'react'

//創建上下文

const?NumContext?=?createContext()

//?創建子組件

function?Child()?{

????//?使用上下文

????const?{?state?}?=?useContext(NumContext)

????//?console.log(useContext(NumContext));

????return?<h1>{state.num}</h1>

????//?{state.data.name}

}

//?創建組件

function?Dispatch()?{

????const?{?dispatch?}?=?useContext(NumContext)

????return?(

????????<button?onClick={()?=>?dispatch({?type:?'addFn',?value:?10 })}>累加</button>

????)

}

function?numReducer(state,?action)?{

????let?newState?=?JSON.parse(JSON.stringify(state))

????switch?(action.type)?{

????????case?"addFn":

????????????newState.num?+=?action.value

????????????break;

????????default:

????????????break;

????}

????return?newState

}

export?default?function?App1()?{

????//?從useReducer這個hook結構出這兩個對象useReducer(第一個參數是函數,第二個參數是傳遞初始的值或者信息)

????const?[state,?dispatch]?=?useReducer(numReducer,?{?num:?0,?data:?{?name:?'你好世界'?}?})

????//?console.log(useReducer(numReducer,?{?num:?0?}));

????return?(

????????<div>

????????????{/*?//?Provider的value屬性,有兩種傳遞參數的形式,第一種是直接傳值,第二種是以對象的形式傳值?*/}

????????????<NumContext.Provider?value={{?state,?dispatch?}}>

????????????????<Child?/>

????????????????<Dispatch?/>

????????????</NumContext.Provider>

????????</div>

????)

}

5.useRef

import?React?from?'react'

import?{?useRef?}?from?'react'

export?default?function?App4()?{

????//?一開始給null的原因是不知道把ref給那個元素

????const?element?=?useRef(null)

????return?(

????????<div>

????????????{/*?沒有input的value值沒有放在state里面的是不受控組件?*/}

????????????<input?type="text"?ref={element}?/>

????????????<button?onClick={()?=>?console.log(element.current.value)}>按鈕</button>

????????</div?>

????)

}


Fragment和空標簽(react中按需引入)

<ul>

????????????????????{

????????????????????????//?eslint-disable-next-line

????????????????????????this.state.arr.map((item,?index)?=>?{

????????????????????????????return?<Fragment?key={index}>

????????????????????????????????<h1>{item}</h1>

????????????????????????????</Fragment>

????????????????????????})

????????????????????}

? ? ? ? </ul>

//?Fragment這個hook作用主要是當你想要循環的時候比如又不想要li標簽?但是循環又需要key屬性的時候可以只用Fragment?但是只能是key?放類名之類的是無效且會報錯 空標簽無法寫屬性


錯誤邊界


PureComponent(能夠監聽子組件和父組件里面的props和state的變化 相當于生命周期內判斷和上一個是否相等不相等就返回false相等就返回true不往下執行)


高階組件HOC:本質是函數(高階組件就是函數里面返回組件)

import?React,?{?Component?}?from?'react'

//?創建兩個低階的組件

class?Sub1?extends?Component?{

????render()?{

????????return?(

????????????<h1>{this.props.num}</h1>

????????)

????}

}

class?Sub2?extends?Component?{

????//?state?=?{

????//?????num:?1

????//?}

????render()?{

????????return?(

????????????<h1>{this.props.num}</h1>

????????)

????}

????//?componentDidMount()?{

????//?????setTimeout(()?=>?{

????//?????????this.setState({

????//?????????????num:?4

????//?????????})

????//?????},?4000)

????//?}

}

//?高階組件HOC本質是一個函數???高階組價就是函數里返回組件

//?高階函數是函數里面返回函數

const?HocFn?=?(Comp,?timeout,?mynum)?=>?{

????return?(

????????//?高階函數里面規定函數名可以不寫

????????class?extends?Component?{

????????????state?=?{

????????????????num:?1

????????????}

????????????render()?{

????????????????return?(

????????????????????<Comp?num={this.state.num}?/>

????????????????)

????????????}

????????????componentDidMount()?{

????????????????setTimeout(()?=>?{

????????????????????this.setState({

????????????????????????num:?mynum

????????????????????})

????????????????},?timeout)

????????????}

????????}

????)

}

const?Sub1Fn?=?HocFn(Sub1,?2000,?100)

const?Sub2Fn?=?HocFn(Sub2,?2000,?200)

export?default?function?App7()?{

????return?(

????????<div>

????????????<Sub1Fn></Sub1Fn>

????????????<hr?/>

????????????<Sub2Fn></Sub2Fn>

????????</div>

????)

}

高階函數HOF:本質是函數(高階組件就是函數里面返回函數)



懶加載loadlazy和suspense一起使用

1.創建一個子組件和一個父組件

2.父組件中constSub=React.lazy(()=>import('.子組件路徑'));

3.react中引入suspense

4.父組件中<Suspense fallback={<div>loading...</div>}> <子組件/> </Suspense>



?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容