最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

React深入淺出分析Hooks源碼

 更新時(shí)間:2022年11月04日 12:01:00   作者:goClient1992  
在react類組件(class)寫法中,有setState和生命周期對(duì)狀態(tài)進(jìn)行管理,但是在函數(shù)組件中不存在這些,故引入hooks(版本:>=16.8),使開發(fā)者在非class的情況下使用更多react特性

useState 解析

useState 使用

通常我們這樣來使用 useState 方法

function App() {
  const [num, setNum] = useState(0);
  const add = () => {
    setNum(num + 1);
  };
  return (
    <div>
      <p>數(shù)字: {num}</p>
      <button onClick={add}> +1 </button>
    </div>
  );
}

useState 的使用過程,我們先模擬一個(gè)大概的函數(shù)

function useState(initialValue) {
  var value = initialValue
  function setState(newVal) {    
    value = newVal
  }
  return [value, setState]
}

這個(gè)代碼有一個(gè)問題,在執(zhí)行 useState 的時(shí)候每次都會(huì) var _val = initialValue,初始化數(shù)據(jù);

于是我們可以用閉包的形式來保存狀態(tài)。

const MyReact = (function() {
   // 定義一個(gè) value 保存在該模塊的全局中
  let value
  return {
    useState(initialValue) {
      value = value || initialValue 
      function setState(newVal) {
        value = newVal
      }
      return [value, setState]
    }
  }
})()

這樣在每次執(zhí)行的時(shí)候,就能夠通過閉包的形式 來保存 value。

不過這個(gè)還是不符合 react 中的 useState。因?yàn)樵趯?shí)際操作中會(huì)出現(xiàn)多次調(diào)用,如下。

function App() {
  const [name, setName] = useState('Kevin');
  const [age, setAge] = useState(0);
  const handleName = () => {
    setNum('Dom');
  };
  const handleAge = () => {
    setAge(age + 1);
  };
  return (
    <div>
      <p>姓名: {name}</p>
      <button onClick={handleName}> 改名字 </button>
       <p>年齡: {age}</p>
      <button onClick={handleAge}> 加一歲 </button>
    </div>
  );
}

因此我們需要在改變 useState 儲(chǔ)存狀態(tài)的方式

useState 模擬實(shí)現(xiàn)

const MyReact = (function() {
  // 開辟一個(gè)儲(chǔ)存 hooks 的空間
  let hooks = []; 
  // 指針從 0 開始
  let currentHook = 0 
  return {
    // 偽代碼 解釋重新渲染的時(shí)候 會(huì)初始化 currentHook
    render(Component) {
      const Comp = Component()
      Comp.render()
      currentHook = 0 // 重新渲染時(shí)候改變 hooks 指針
      return Comp
    },      
    useState(initialValue) {
      hooks[currentHook] = hooks[currentHook] || initialValue
      const setStateHookIndex = currentHook
      // 這里我們暫且默認(rèn) setState 方式第一個(gè)參數(shù)不傳 函數(shù),直接傳狀態(tài)
      const setState = newState => (hooks[setStateHookIndex] = newState)
      return [hooks[currentHook++], setState]
    }
  }
})()

因此當(dāng)重新渲染 App 的時(shí)候,再次執(zhí)行 useState 的時(shí)候傳入的參數(shù) kevin , 0 也就不會(huì)去使用,而是直接拿之前 hooks 存儲(chǔ)好的值。

hooks 規(guī)則

官網(wǎng) hoos 規(guī)則中明確的提出 hooks 不要再循環(huán),條件或嵌套函數(shù)中使用。

為什么不可以?

我們來看下

下面這樣一段代碼。執(zhí)行 useState 重新渲染,和初始化渲染 順序不一樣就會(huì)出現(xiàn)如下問題

如果了解了上面 useState 模擬寫法的存儲(chǔ)方式,那么這個(gè)問題的原因就迎刃而解了。相關(guān)參考視頻:傳送門

useEffect 解析

useEffect 使用

初始化會(huì) 打印一次 ‘useEffect_execute’, 改變年齡重新render,會(huì)再打印, 改變名字重新 render, 不會(huì)打印。因?yàn)橐蕾嚁?shù)組里面就監(jiān)聽了 age 的值

import React, { useState, useEffect } from 'react';
function App() {
  const [name, setName] = useState('Kevin');
  const [age, setAge] = useState(0);
  const handleName = () => {
    setName('Don');
  };
  const handleAge = () => {
    setAge(age + 1);
  };
  useEffect(()=>{
    console.log('useEffect_execute')
  }, [age])
  return (
    <div>
      <p>姓名: {name}</p>
      <button onClick={handleName}> 改名字 </button>
      <p>年齡: {age}</p>
      <button onClick={handleAge}> 加一歲 </button>
    </div>
  );
}
export default App;

useEffect 的模擬實(shí)現(xiàn)

const MyReact = (function() {
  // 開辟一個(gè)儲(chǔ)存 hooks 的空間
  let hooks = []; 
  // 指針從 0 開始
  let currentHook = 0 ;
  // 定義個(gè)模塊全局的 useEffect 依賴
  let deps;
  return {
    // 偽代碼 解釋重新渲染的時(shí)候 會(huì)初始化 currentHook
    render(Component) {
      const Comp = Component()
      Comp.render()
      currentHook = 0 // 重新渲染時(shí)候改變 hooks 指針
      return Comp
    },      
    useState(initialValue) {
      hooks[currentHook] = hooks[currentHook] || initialValue
      const setStateHookIndex = currentHook
      // 這里我們暫且默認(rèn) setState 方式第一個(gè)參數(shù)不傳 函數(shù),直接傳狀態(tài)
      const setState = newState => (hooks[setStateHookIndex] = newState)
      return [hooks[currentHook++], setState]
    }
    useEffect(callback, depArray) {
      const hasNoDeps = !depArray
      // 如果沒有依賴,說明是第一次渲染,或者是沒有傳入依賴參數(shù),那么就 為 true
      // 有依賴 使用 every 遍歷依賴的狀態(tài)是否變化, 變化就會(huì) true
      const hasChangedDeps = deps ? !depArray.every((el, i) => el === deps[i]) : true
      // 如果沒有依賴, 或者依賴改變
      if (hasNoDeps || hasChangedDeps) {
        // 執(zhí)行 
        callback()
        // 更新依賴
        deps = depArray
      }
    },

  }
})()

useEffect 注意事項(xiàng)

依賴項(xiàng)要真實(shí)

依賴需要想清楚。

剛開始使用 useEffect 的時(shí)候,我只有想重新觸發(fā) useEffect 的時(shí)候才會(huì)去設(shè)置依賴

那么也就會(huì)出現(xiàn)如下的問題。

希望的效果是界面中一秒增加一歲

import React, { useState, useEffect } from 'react';
function App() {
  const [name, setName] = useState('Kevin');
  const [age, setAge] = useState(0);
  const handleName = () => {
    setName('Don');
  };
  const handleAge = () => {
    setAge(age + 1);
  };
  useEffect(() => {
    setInterval(() => {
      setAge(age + 1);
      console.log(age)
    }, 1000);
  }, []);
  return (
    <div>
      <p>姓名: {name}</p>
      <button onClick={handleName}> 改名字 </button>
      <p>年齡: {age}</p>
      <button onClick={handleAge}> 加一歲 </button>
    </div>
  );
}
export default App;

其實(shí)你會(huì)發(fā)現(xiàn) 這里界面就增加了 一次 年齡。究其原因:

**在第一次渲染中,age0。因此,setAge(age+ 1)在第一次渲染中等價(jià)于setAge(0 + 1)。然而我設(shè)置了0依賴為空數(shù)組,那么之后的 useEffect 不會(huì)再重新運(yùn)行,它后面每一秒都會(huì)調(diào)用setAge(0 + 1) **

也就是當(dāng)我們需要 依賴 age 的時(shí)候我們 就必須再 依賴數(shù)組中去記錄他的依賴。這樣useEffect 才會(huì)正常的給我們?nèi)ミ\(yùn)行。

所以我們想要每秒都遞增的話有兩種方法

方法一:

真真切切的把你所依賴的狀態(tài)填寫到 數(shù)組中

  // 通過監(jiān)聽 age 的變化。來重新執(zhí)行 useEffect 內(nèi)的函數(shù)
  // 因此這里也就需要記錄定時(shí)器,當(dāng)卸載的時(shí)候我們?nèi)デ蹇斩〞r(shí)器,防止多個(gè)定時(shí)器重新觸發(fā)
  useEffect(() => {
    const id = setInterval(() => {
      setAge(age + 1);
    }, 1000);
    return () => {
      clearInterval(id)
    };
  }, [age]);

方法二

useState 的參數(shù)傳入 一個(gè)方法。

注:上面我們模擬的 useState 并沒有做這個(gè)處理 后面我會(huì)講解源碼中去解析。

useEffect(() => {
    setInterval(() => {
      setAge(age => age + 1);
    }, 1000);
  }, []);

useEffect 只運(yùn)行了一次,通過 useState 傳入函數(shù)的方式它不再需要知道當(dāng)前的age值。因?yàn)?React render 的時(shí)候它會(huì)幫我們處理

這正是setAge(age => age + 1)做的事情。再重新渲染的時(shí)候他會(huì)幫我們執(zhí)行這個(gè)方法,并且傳入最新的狀態(tài)。

所以我們做到了去時(shí)刻改變狀態(tài),但是依賴中卻不用寫這個(gè)依賴,因?yàn)槲覀儗⒃镜氖褂玫降囊蕾囈瞥恕#ㄟ@句話表達(dá)感覺不到位)

接口無限請(qǐng)求問題

剛開始使用 useEffect 的我,在接口請(qǐng)求的時(shí)候常常會(huì)這樣去寫代碼。

props 里面有 頁(yè)碼,通過切換頁(yè)碼,希望監(jiān)聽頁(yè)碼的變化來重新去請(qǐng)求數(shù)據(jù)

// 以下是偽代碼 
// 這里用 dva 發(fā)送請(qǐng)求來模擬
import React, { useState, useEffect } from 'react';
import { connect } from 'dva';
function App(props) {
  const { goods, dispatch, page } = props;
  useEffect(() => {
    // 頁(yè)面完成去發(fā)情請(qǐng)求
   dispatch({
      type: '/goods/list',
      payload: {page, pageSize:10},
    });
    // xxxx 
  }, [props]);
  return (
    <div>
      <p>商品: {goods}</p>
     <button>點(diǎn)擊切下一頁(yè)</button>
    </div>
  );
}
export default connect(({ goods }) => ({
  goods,
}))(App);

然后得意洋洋的刷新界面,發(fā)現(xiàn) Network 中瘋狂循環(huán)的請(qǐng)求接口,導(dǎo)致頁(yè)面的卡死。

究其原因是因?yàn)樵谝蕾囍?,我們通過接口改變了狀態(tài) props 的更新, 導(dǎo)致重新渲染組件,導(dǎo)致會(huì)重新執(zhí)行 useEffect 里面的方法,方法執(zhí)行完成之后 props 的更新, 導(dǎo)致重新渲染組件,依賴項(xiàng)目是對(duì)象,引用類型發(fā)現(xiàn)不相等,又去執(zhí)行 useEffect 里面的方法,又重新渲染,然后又對(duì)比,又不相等, 又執(zhí)行。因此產(chǎn)生了無限循環(huán)。

Hooks 源碼解析

該源碼位置: react/packages/react-reconciler/src/ReactFiberHooks.js

const Dispatcher={
  useReducer: mountReducer,
  useState: mountState,
  // xxx 省略其他的方法
}

mountState 源碼

function mountState<S>(
  initialState: (() => S) | S,
): [S, Dispatch<BasicStateAction<S>>] {
    /*    mountWorkInProgressHook 方法 返回初始化對(duì)象    {        memoizedState: null,        baseState: null,         queue: null,        baseUpdate: null,        next: null,      }    */
  const hook = mountWorkInProgressHook();
 // 如果傳入的是函數(shù) 直接執(zhí)行,所以第一次這個(gè)參數(shù)是 undefined
  if (typeof initialState === 'function') {
    initialState = initialState();
  }
  hook.memoizedState = hook.baseState = initialState;
  const queue = (hook.queue = {
    last: null,
    dispatch: null,
    lastRenderedReducer: basicStateReducer,
    lastRenderedState: (initialState: any),
  });
    /*    定義 dispatch 相當(dāng)于    const dispatch = queue.dispatch =    dispatchAction.bind(null,currentlyRenderingFiber,queue);    */ 
  const dispatch: Dispatch<
    BasicStateAction<S>,
  > = (queue.dispatch = (dispatchAction.bind(
    null,
    // Flow doesn't know this is non-null, but we do.
    ((currentlyRenderingFiber: any): Fiber),
    queue,
  ): any));
 // 可以看到這個(gè)dispatch就是dispatchAction綁定了對(duì)應(yīng)的 currentlyRenderingFiber 和 queue。最后return:
  return [hook.memoizedState, dispatch];
}

dispatchAction 源碼

function dispatchAction<A>(fiber: Fiber, queue: UpdateQueue<A>, action: A) {
  //... 省略驗(yàn)證的代碼
  const alternate = fiber.alternate;
    /*    這其實(shí)就是判斷這個(gè)更新是否是在渲染過程中產(chǎn)生的,currentlyRenderingFiber只有在FunctionalComponent更新的過程中才會(huì)被設(shè)置,在離開更新的時(shí)候設(shè)置為null,所以只要存在并更產(chǎn)生更新的Fiber相等,說明這個(gè)更新是在當(dāng)前渲染中產(chǎn)生的,則這是一次reRender。所有更新過程中產(chǎn)生的更新記錄在renderPhaseUpdates這個(gè)Map上,以每個(gè)Hook的queue為key。對(duì)于不是更新過程中產(chǎn)生的更新,則直接在queue上執(zhí)行操作就行了,注意在最后會(huì)發(fā)起一次scheduleWork的調(diào)度。    */
  if (
    fiber === currentlyRenderingFiber ||
    (alternate !== null && alternate === currentlyRenderingFiber)
  ) {
    didScheduleRenderPhaseUpdate = true;
    const update: Update<A> = {
      expirationTime: renderExpirationTime,
      action,
      next: null,
    };
    if (renderPhaseUpdates === null) {
      renderPhaseUpdates = new Map();
    }
    const firstRenderPhaseUpdate = renderPhaseUpdates.get(queue);
    if (firstRenderPhaseUpdate === undefined) {
      renderPhaseUpdates.set(queue, update);
    } else {
      // Append the update to the end of the list.
      let lastRenderPhaseUpdate = firstRenderPhaseUpdate;
      while (lastRenderPhaseUpdate.next !== null) {
        lastRenderPhaseUpdate = lastRenderPhaseUpdate.next;
      }
      lastRenderPhaseUpdate.next = update;
    }
  } else {
    const currentTime = requestCurrentTime();
    const expirationTime = computeExpirationForFiber(currentTime, fiber);
    const update: Update<A> = {
      expirationTime,
      action,
      next: null,
    };
    flushPassiveEffects();
    // Append the update to the end of the list.
    const last = queue.last;
    if (last === null) {
      // This is the first update. Create a circular list.
      update.next = update;
    } else {
      const first = last.next;
      if (first !== null) {
        // Still circular.
        update.next = first;
      }
      last.next = update;
    }
    queue.last = update;
    scheduleWork(fiber, expirationTime);
  }
}

mountReducer 源碼

多勒第三個(gè)參數(shù),是函數(shù)執(zhí)行,默認(rèn)初始狀態(tài) undefined

其他的和 上面的 mountState 大同小異

function mountReducer<S, I, A>(
  reducer: (S, A) => S,
  initialArg: I,
  init?: I => S,
): [S, Dispatch<A>] {
  const hook = mountWorkInProgressHook();
  let initialState;
  if (init !== undefined) {
    initialState = init(initialArg);
  } else {
    initialState = ((initialArg: any): S);
  }
    // 其他和 useState 一樣
  hook.memoizedState = hook.baseState = initialState;
  const queue = (hook.queue = {
    last: null,
    dispatch: null,
    lastRenderedReducer: reducer,
    lastRenderedState: (initialState: any),
  });
  const dispatch: Dispatch<A> = (queue.dispatch = (dispatchAction.bind(
    null,
    // Flow doesn't know this is non-null, but we do.
    ((currentlyRenderingFiber: any): Fiber),
    queue,
  ): any));
  return [hook.memoizedState, dispatch];
}

通過 react 源碼中,可以看出 useState 是特殊的 useReducer

  • 可見useState不過就是個(gè)語(yǔ)法糖,本質(zhì)其實(shí)就是useReducer
  • updateState 復(fù)用了 updateReducer(區(qū)別只是 updateState 將 reducer 設(shè)置為 updateReducer)
  • mountState 雖沒直接調(diào)用 mountReducer,但是幾乎大同小異(區(qū)別只是 mountState 將 reducer 設(shè)置為basicStateReducer)

注:這里僅是 react 源碼,至于重新渲染這塊 react-dom 還沒有去深入了解。

更新:

分兩種情況,是否是 reRender,所謂reRender就是說在當(dāng)前更新周期中又產(chǎn)生了新的更新,就繼續(xù)執(zhí)行這些更新知道當(dāng)前渲染周期中沒有更新為止

他們基本的操作是一致的,就是根據(jù) reducerupdate.action 來創(chuàng)建新的 state,并賦值給Hook.memoizedState 以及 Hook.baseState。

注意這里,對(duì)于非reRender得情況,我們會(huì)對(duì)每個(gè)更新判斷其優(yōu)先級(jí),如果不是當(dāng)前整體更新優(yōu)先級(jí)內(nèi)得更新會(huì)跳過,第一個(gè)跳過得Update會(huì)變成新的baseUpdate,他記錄了在之后所有得Update,即便是優(yōu)先級(jí)比他高得,因?yàn)樵谒粓?zhí)行得時(shí)候,需要保證后續(xù)的更新要在他更新之后的基礎(chǔ)上再次執(zhí)行,因?yàn)榻Y(jié)果可能會(huì)不一樣。

來源

preact 中的 hooks

Preact 最優(yōu)質(zhì)的開源 React 替代品!(輕量級(jí) 3kb)

注意:這里的替代是指如果不用 react 的話,可以使用這個(gè)。而不是取代。

useState 源碼解析

調(diào)用了 useReducer 源碼

export function useState(initialState) {
    return useReducer(invokeOrReturn, initialState);
}

useReducer 源碼解析

// 模塊全局定義
/** @type {number} */
let currentIndex; // 狀態(tài)的索引,也就是前面模擬實(shí)現(xiàn) useState 時(shí)候所說的指針
let currentComponent; // 當(dāng)前的組件
export function useReducer(reducer, initialState, init) {
    /** @type {import('./internal').ReducerHookState} */
    // 通過 getHookState 方法來獲取 hooks 
    const hookState = getHookState(currentIndex++);
    // 如果沒有組件 也就是初始渲染
    if (!hookState._component) {
        hookState._component = currentComponent;
        hookState._value = [
            // 沒有 init 執(zhí)行 invokeOrReturn
                // invokeOrReturn 方法判斷 initialState 是否是函數(shù)
                // 是函數(shù) initialState(null) 因?yàn)槌跏蓟瘺]有值默認(rèn)為null
                // 不是函數(shù) 直接返回 initialState
            !init ? invokeOrReturn(null, initialState) : init(initialState),
            action => {
                // reducer == invokeOrReturn
                const nextValue = reducer(hookState._value[0], action);
                // 如果當(dāng)前的值,不等于 下一個(gè)值
                // 也就是更新的狀態(tài)的值,不等于之前的狀態(tài)的值
                if (hookState._value[0]!==nextValue) {
                    // 儲(chǔ)存最新的狀態(tài)
                    hookState._value[0] = nextValue;
                    // 渲染組件
                    hookState._component.setState({});
                }
            }
        ];
    }
    // hookState._value 數(shù)據(jù)格式也就是 [satea:any, action:Function] 的數(shù)據(jù)格式拉
    return hookState._value;
}

getHookState 方法

function getHookState(index) {
    if (options._hook) options._hook(currentComponent);
    const hooks = currentComponent.__hooks || (currentComponent.__hooks = { _list: [], _pendingEffects: [], _pendingLayoutEffects: [] });

    if (index >= hooks._list.length) {
        hooks._list.push({});
    }
    return hooks._list[index];
}

invokeOrReturn 方法

function invokeOrReturn(arg, f) {
    return typeof f === 'function' ? f(arg) : f;
}

總結(jié)

使用 hooks 幾個(gè)月了?;旧纤蓄惤M件我都使用函數(shù)式組件來寫?,F(xiàn)在 react 社區(qū)的很多組件,都也開始支持hooks。大概了解了點(diǎn)重要的源碼,做到知其然也知其所以然,那么在實(shí)際工作中使用他可以減少不必要的 bug,提高效率。

到此這篇關(guān)于React深入淺出分析Hooks源碼的文章就介紹到這了,更多相關(guān)React Hooks內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 一文帶你掌握React類式組件中setState的應(yīng)用

    一文帶你掌握React類式組件中setState的應(yīng)用

    這篇文章主要為大家詳細(xì)介紹了介紹了React類式組件中setState的三種寫法以及簡(jiǎn)單討論下setState?到底是同步的還是異步的,感興趣的可以了解下
    2024-02-02
  • 詳解各版本React路由的跳轉(zhuǎn)的方法

    詳解各版本React路由的跳轉(zhuǎn)的方法

    這篇文章主要介紹了詳解各版本React路由的跳轉(zhuǎn)的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-05-05
  • React組件refs的使用詳解

    React組件refs的使用詳解

    這篇文章主要介紹了React組件refs的使用詳解,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-02-02
  • react MPA 多頁(yè)配置詳解

    react MPA 多頁(yè)配置詳解

    這篇文章主要介紹了react MPA 多頁(yè)配置詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-10-10
  • React配置子路由的實(shí)現(xiàn)

    React配置子路由的實(shí)現(xiàn)

    本文主要介紹了React配置子路由的實(shí)現(xiàn),我們來通過一個(gè)簡(jiǎn)單的例子解釋一下如何配置子路由,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-06-06
  • React Native react-navigation 導(dǎo)航使用詳解

    React Native react-navigation 導(dǎo)航使用詳解

    本篇文章主要介紹了React Native react-navigation 導(dǎo)航使用詳解,詳解的介紹了react-navigation導(dǎo)航的使用,具有一定的參考價(jià)值,有興趣的可以了解一下
    2017-12-12
  • React更新渲染原理深入分析

    React更新渲染原理深入分析

    什么是re-render(重新渲染)?哪些是必要的re-render?哪些是非必要的re-render?如果你對(duì)這些問題還不是很明白,那么可以在這篇文章中找到答案
    2022-12-12
  • React之Hooks詳解

    React之Hooks詳解

    這篇文章主要介紹了React hooks的優(yōu)缺點(diǎn)詳解,幫助大家更好的理解和學(xué)習(xí)使用React,感興趣的朋友可以了解下, 希望能夠給你帶來幫助
    2021-09-09
  • 40行代碼把Vue3的響應(yīng)式集成進(jìn)React做狀態(tài)管理

    40行代碼把Vue3的響應(yīng)式集成進(jìn)React做狀態(tài)管理

    這篇文章主要介紹了40行代碼把Vue3的響應(yīng)式集成進(jìn)React做狀態(tài)管理,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-05-05
  • React Native 啟動(dòng)流程詳細(xì)解析

    React Native 啟動(dòng)流程詳細(xì)解析

    這篇文章主要介紹了React Native 啟動(dòng)流程簡(jiǎn)析,文以 react-native-cli 創(chuàng)建的示例工程(安卓部分)為例,給大家分析 React Native 的啟動(dòng)流程,需要的朋友可以參考下
    2021-08-08

最新評(píng)論

剑阁县| 桃江县| 湾仔区| 济阳县| 靖州| 南通市| 海丰县| 龙南县| 桑日县| 乌拉特中旗| 民勤县| 玉田县| 阿合奇县| 龙泉市| 宝山区| 静宁县| 富民县| 德安县| 张掖市| 尼玛县| 桦川县| 巢湖市| 开阳县| 长治市| 丹东市| 易门县| 广州市| 峡江县| 彩票| 前郭尔| 新平| 兴山县| 临朐县| 长宁县| 如东县| 云龙县| 盈江县| 镇原县| 安康市| 灌南县| 安吉县|