日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢(xún)
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
讓我一起聊聊Hook使用總結(jié)

自React 16.8支持hook以來(lái),RN也在0.59版本支持了hook,而且官方給出的組件實(shí)例也分為了class和hook兩個(gè)版本,可以遇見(jiàn)hook是未來(lái)的趨勢(shì)。恰巧最近重構(gòu)RN項(xiàng)目,把最近遇到的問(wèn)題和思考記錄一下。

今天是總結(jié)課。

重構(gòu)

重構(gòu),我想這個(gè)詞可能沒(méi)有多少人愿意做,在業(yè)務(wù)迭代頻繁的今天,重構(gòu)意味著資源的消耗,而且承擔(dān)著未知的風(fēng)險(xiǎn),那么為什么還要重構(gòu)?

主要有以下思考:

  • 代碼沉郁,不敢刪除舊代碼,舊有的代碼邏輯不熟,關(guān)聯(lián)關(guān)系不清,隨著業(yè)務(wù)的迭代,代碼越來(lái)越多。
  • 模塊化不清晰,文件混亂。
  • 規(guī)范不統(tǒng)一,注釋不明確,代碼雜亂。文件查找困難。
  • 工程化不完善,請(qǐng)求不統(tǒng)一,如遇到接口參數(shù)變更,需要修改多處。
  • 組件化不完善,公共組件不統(tǒng)一。

hook化

hook化一個(gè)很重要的就是class邏輯的復(fù)用,比如:

 
 
 
  1. // class
  2. this.setState({
  3.     count:0
  4. },()=>{
  5.     // 修改數(shù)據(jù)成功之后 處理的邏輯
  6. })
  7. // hook
  8. useEffect(()=>{
  9.     // 監(jiān)控count值的變更 處理邏輯
  10. },[count])

如果我們需要監(jiān)控的值很多,是否需要寫(xiě)很多useEffect呢?這里會(huì)用到另一個(gè)概念,細(xì)粒度組件。寫(xiě)hook寫(xiě)多了,會(huì)把一些需要處理的業(yè)務(wù)組件都抽離出來(lái),每個(gè)組件只管自己的狀態(tài)。這樣就會(huì)極大減少了父組件的業(yè)務(wù)堆積和state堆積。

組件多了就會(huì)涉及到組件傳值,這里有三種場(chǎng)景:

  • context包裹子組件
  • memo + context + reducer 組件傳值
  • ref + useImperativeHandle + forwardRef 暴露狀態(tài)給父組件
  • props 組件傳值

props傳值,通過(guò)標(biāo)簽屬性傳遞。

 
 
 
  1. // props 通過(guò)標(biāo)簽傳值
  2. // 
  3. export default CenterMenu(props){
  4.     const { style, list } = props;
  5.     //. ...
  6. }

context包裹的話,就會(huì)把所有狀態(tài)都放在了父組件,就會(huì)造成context很臃腫。

 
 
 
  1.     value={{
  2.         serviceBill,
  3.         patientInfo,
  4.         batchList,
  5.         navigation,
  6.         ...params
  7. }}>
  8.     // ...View
  9.     
  10. //
  11. const Footer = () => {
  12.     const  data  =  useContext(PerfectInfoContext);
  13.     // ...
  14. }
  15. export default Footer;

用context包裹一個(gè)Reducer,再用memo緩存,我們就可以在其他函數(shù)組件中去觸發(fā)狀態(tài)變更。

  
 
 
  1. const initState={
  2.  isLoading: true,
  3.  isSignOut: false,
  4.  userToken: null,
  5.  routes
  6. }
  7. const reducer=(prevState, action)=>{ // switch}
  8. const [state, dispatch] = useReducer(reducer, initState);
  9. const authContextProps=(dispatch)=>{
  10.     return {
  11.     signIn:async()=>{ // dispatch },
  12.     signOut:async()=>{ // dispatch}
  13.     }
  14. }
  15. const authContextData = useMemo(authContextProps(dispatch), []);
  16. return (
  17.   
  18.     // view
  19.    
  20. );
  21. // 其他函數(shù)組件
  22. const { signOut } =  useContext(AuthContext);

細(xì)粒度的話,ref應(yīng)該是一個(gè)很好的選擇,拿輸入框組件舉例:

  
 
 
  1. function FancyInput(props, ref) {
  2.     const inputRef = useRef(null);
  3.     // 暴露給父組件使用
  4.     useImperativeHandle(ref, () => ({
  5.     focus: () => {
  6.         inputRef.current.focus();
  7.     }
  8.     // 其他方法也可以或者state
  9.     }));
  10.     return ;
  11. }
  12. export default forwardRef(FancyInput);
  13. // 父組件
  14. const fancyRef = useRef(null);
  15. // useEffect、 onPress中使用
  16. const onPress=()=>{
  17.     fancyRef.current?.focus()
  18. }

路由

靈活的路由配置也是我們重構(gòu)要考慮的一部分,怎么在RN中實(shí)現(xiàn)vue項(xiàng)目的路由配置呢?這需要借助React Navigation 5.x以上版本的Stack。比較可惜的是4.x的 NavigationEvents組件被移除。

  
 
 
  1. // 4.x可使用 4.x之后被移除
  2.     
  3.         onWillFocus={payload => console.log('will focus', payload)}
  4.         onDidFocus={payload => console.log('did focus', payload)}
  5.         onWillBlur={payload => console.log('will blur', payload)}
  6.         onDidBlur={payload => console.log('did blur', payload)}
  7.     />
  8.     {/* Your view code  */}

5.x版本有點(diǎn)倉(cāng)促,已不在維護(hù),變更較大,核心代碼分為native、stack等,可以單獨(dú)使用。現(xiàn)在的版本6.x大部分api都做了變更,不推薦單獨(dú)升級(jí)。

  
 
 
  1. // 屏幕事件focus、blur、beforeRemove、state
  2. React.useEffect(()  =>  {
  3.     const unsubscribe = navigation.addListener('focus',  ()  =>  {
  4.         // do something
  5.     });
  6.     return unsubscribe;
  7. },  [navigation]);

回到路由配置上,我們可以通過(guò)routes來(lái)控制路由變化:

  
 
 
  1. // 路由配置
  2. export const routes = [
  3.     ...roleRouters,
  4.     {
  5.         name: 'Home',
  6.         screen: HomeScreen,
  7.         hidden: false,
  8.         options: {},
  9.     },
  10.     ...personRouters,
  11.     ...ordersRouters,
  12.     ...goodsRouters,
  13.     ...customerRouters,
  14.     ...taskRouters,
  15.     ...otherRouters,
  16. ];
  17.     
  18.         {state.userToken ==  null  ? (
  19.             name='Login'
  20.             component={LoginScreen}/>) : 
  21.             (state.routes.map((e, i) => {
  22.                 if (!e.hidden) {
  23.                     return (
  24.                         
  25.                             key={i.toString()}
  26.                             name={e.name}
  27.                             params={e.params}
  28.                 component={e.screen}/>
  29.             );
  30.         }})
  31.         )}
  32.     {/* 公共路由 無(wú)論是否登錄都可以訪問(wèn) */}
  33.     {commonRoutes.map((e, i) => )}
  34.     

如果你覺(jué)得import導(dǎo)入太多的話,navigation也提供了支持,你也可以動(dòng)態(tài)導(dǎo)入:

  
 
 
  1. // 動(dòng)態(tài)導(dǎo)入
  2. export const routes = [
  3.     {
  4.         name: 'Home',
  5.     getComponent: () =>  require('@/pages/other/cmsWeb').default,
  6.     options: { header: () => {} },
  7.     },
  8. ];
  9.     
  10.         state.routes.map(
  11.             (e, i) => ;
  12.         )
  13.     

navigation提供了一個(gè)輔助效果,回到頂部:

  
 
 
  1. import  *  as  React  from  'react';
  2. import  {  ScrollView  }  from  'react-native';
  3. import  { useScrollToTop }  from  '@react-navigation/native';
  4. function  Albums()  {
  5.     const ref =  React.useRef(null);
  6.     useScrollToTop(ref); // ScrollView或者FlatList
  7.     return  {/* content */};
  8. }

工程化配置

除了babel、eslint配置外,就是模塊化的管理,路由模塊化、頁(yè)面模塊化、api模塊化。工具方法、共用組件、公共hook、公共資源、本地常量,以及屏幕適配方案,剩下就是規(guī)范統(tǒng)一,這樣一個(gè)小中項(xiàng)目基本就可以hold住了。

hook之前都停留著概念上,這次的落地能發(fā)現(xiàn)一些問(wèn)題,也能跟貼切與class對(duì)比,目前還是粗淺使用,更加復(fù)雜的場(chǎng)景還待處理。

補(bǔ)充一點(diǎn)就是,在RN中require的本地圖片返回的是一個(gè)id,那么我們有集中處理必要了。


分享名稱(chēng):讓我一起聊聊Hook使用總結(jié)
分享鏈接:http://www.dlmjj.cn/article/djgcsdj.html