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

詳解Stack?Navigator中使用自定義的Render?Callback

 更新時(shí)間:2022年10月12日 08:58:07   作者:前百花真君  
這篇文章主要為大家介紹了Stack?Navigator中使用自定義的Render?Callback使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

Stack Navigator使用component props傳遞組件

通常來(lái)說(shuō),Stack Navigator的默認(rèn)用法,是這樣的

<NavigationContainer>\
    <Stack.Navigator>\
        <Stack.Screen name="Home" component={HomeScreen} />\
    </Stack.Navigator>\
</NavigationContainer>

自定義的組件HomeScreen是作為component屬性,傳遞給Stack.Screen的。這種默認(rèn)的做法,會(huì)讓Stack.Screen對(duì)Screen Component進(jìn)行優(yōu)化,避免了很多不必要的渲染。官方文檔中,是這樣描述的。

Note: By default, React Navigation applies optimizations to screen components to prevent unnecessary renders. Using a render callback removes those optimizations. So if you use a render callback, you'll need to ensure that you use React.memo or React.PureComponent for your screen components to avoid performance issues.

從這段話中,我們可以看出,當(dāng)使用自定義的render callback時(shí),避免組件重復(fù)渲染的工作,就移交給了使用者。render callback通常是為了傳遞extra props,但是優(yōu)化方式和extra props是沒(méi)什么關(guān)系的,以下的例子中,為了避免干擾,沒(méi)有新引入extra props,只是用stack navigator傳遞給組件的默認(rèn)屬性來(lái)舉例子。

為了更好的監(jiān)控,HomeScreen是否被重復(fù)渲染,在代碼中打印了一個(gè)隨機(jī)數(shù),便于觀察日志輸出。

無(wú)因素引起組件更新時(shí),使用render callback的效果

下面這段代碼,使用了render callback來(lái)渲染HomeScreen。

const homeInst = (props) => (<HomeScreen {...props} />)

運(yùn)行起來(lái)的效果和不使用render callback的效果是一樣的。在頻繁的HomeScreen和DetailsScreen切換過(guò)程中,因?yàn)闆](méi)有引起HomeScreen重繪的因素存在,所以HomeScreen并沒(méi)有被重復(fù)渲染。

import React from 'react'
import { View, Text, Button } from 'react-native'
import { NavigationContainer } from '@react-navigation/native'
import { createNativeStackNavigator } from '@react-navigation/native-stack'
function HomeScreen({ navigation }) {
  console.log(`home: ${Math.random(new Date().getTime())}`)
  const goToDetail = () => {
    navigation.navigate('Details')
  }
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Home Screen</Text>
      <Button title='Go To Detail' onPress={goToDetail}></Button>
    </View>
  )
}
function DetailsScreen({ navigation }) {
  const goHome = () => {
    navigation.navigate('Home')
  }
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Details Screen</Text>
      <Button title='Go Home' onPress={goHome}></Button>
    </View>
  )
}
const Stack = createNativeStackNavigator()
function App() {
  const homeInst = (props) => (<HomeScreen {...props} />)
  return (
    <NavigationContainer>
      <Stack.Navigator initialRouteName='Home'>
        <Stack.Screen name='Home'>
        {homeInst}
        </Stack.Screen>
        <Stack.Screen name='Details' component={DetailsScreen}/>
      </Stack.Navigator>
    </NavigationContainer>
  )
}
export default App

有因素引起組件更新時(shí),使用component props的效果

為了引起HomeScreen組件的更新,以便驗(yàn)證Screen Navigator是否對(duì)HomeScreen做了避免重復(fù)渲染的優(yōu)化,在代碼中加入了一個(gè)新的狀態(tài)age,當(dāng)點(diǎn)擊Button時(shí),這個(gè)age不斷的自增1,因?yàn)?code>App里有state的更新,所以作為父組件的App會(huì)更新,而作為子組件的HomeScreen通常意義上(不通常的情況下,就是使用了React.memo等優(yōu)化手段)說(shuō),也會(huì)重新渲染。因?yàn)檫@就是React的重繪機(jī)制:從父組件開(kāi)始,一層一層向下重繪。

import React, {useState} from 'react'
import { View, Text, Button } from 'react-native'
import { NavigationContainer } from '@react-navigation/native'
import { createNativeStackNavigator } from '@react-navigation/native-stack'
function HomeScreen({ navigation }) {
  console.log(`home: ${Math.random(new Date().getTime())}`)
  const goToDetail = () => {
    navigation.navigate('Details')
  }
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Home Screen</Text>
      <Button title='Go To detail' onPress={goToDetail}></Button>
    </View>
  )
}
function DetailsScreen({ navigation }) {
  const goHome = () => {
    navigation.navigate('Home')
  }
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Details Screen</Text>
      <Button title='Go Home' onPress={goHome}></Button>
    </View>
  )
}
const Stack = createNativeStackNavigator()
function App() {
  const [age, setAge] = useState(20)
  return (
    <NavigationContainer>
      <Stack.Navigator initialRouteName='Home'>
        <Stack.Screen name='Home' component={HomeScreen} />
        <Stack.Screen name='Details' component={DetailsScreen} />
      </Stack.Navigator>
      <View>
        <Text>{age}</Text>
        <Button title='Increase Age' onPress={() => (setAge(age + 1))}></Button>
      </View>
    </NavigationContainer>
  )
}
export default App

當(dāng)我點(diǎn)擊Button后,發(fā)現(xiàn)HomeScreen并沒(méi)有重繪,所以當(dāng)使用component props傳遞組件時(shí),Stack Navigator確實(shí)是做了防止不必要重繪的優(yōu)化。

具體效果可以參考下面的動(dòng)畫(huà):

有因素引起組件更新時(shí),使用render callback的效果

那么在上面所說(shuō)的場(chǎng)景下,用render callback會(huì)怎么樣呢?答案顯而易見(jiàn),如果沒(méi)有做任何優(yōu)化處理,那么HomeScreen的不必要的重復(fù)渲染,是無(wú)法避免的了。

代碼如下:

import React, { useState } from 'react'
import { View, Text, Button } from 'react-native'
import { NavigationContainer } from '@react-navigation/native'
import { createNativeStackNavigator } from '@react-navigation/native-stack'
function HomeScreen({ navigation }) {
  console.log(`home: ${Math.random(new Date().getTime())}`)
  const goToDetail = () => {
    navigation.navigate('Details')
  }
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Home Screen</Text>
      <Button title='Go To detail' onPress={goToDetail}></Button>
    </View>
  )
}
function DetailsScreen({ navigation }) {
  const goHome = () => {
    navigation.navigate('Home')
  }
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Details Screen</Text>
      <Button title='Go Home' onPress={goHome}></Button>
    </View>
  )
}
const Stack = createNativeStackNavigator()
function App() {
  const [age, setAge] = useState(20)
  const homeInst = (props) => (<HomeScreen {...props} />)
  return (
    <NavigationContainer>
      <Stack.Navigator initialRouteName='Home'>
        <Stack.Screen name='Home'>
          {homeInst}
        </Stack.Screen>
        <Stack.Screen name='Details' component={DetailsScreen} />
      </Stack.Navigator>
      <View>
        <Text>{age}</Text>
        <Button title='Increase Age' onPress={() => (setAge(age + 1))}></Button>
      </View>
    </NavigationContainer>
  )
}
export default App

動(dòng)畫(huà)效果如下:

可以看到,當(dāng)我點(diǎn)擊Button改變App的狀態(tài)時(shí),本來(lái)沒(méi)有必要變化的HomeScreen,就瘋狂的重繪了起來(lái),當(dāng)然每次重繪的結(jié)果,都和之前一樣,這就是無(wú)效的重繪,我們應(yīng)該避免。

有因素引起組件更新時(shí),在render callback中使用React.memo

根據(jù)上面官網(wǎng)文檔給出的提示,如果想避免重繪,應(yīng)該用React.memo (因?yàn)楦杏X(jué)FB已經(jīng)全面擁抱Hook了,所以這里也不考慮PureComponent了)來(lái)包裝你的組件。

const MemoHomeScreen = React.memo(HomeScreen)

說(shuō)一百句,也頂不上一句代碼,具體代碼如下(都是可以copy到你的環(huán)境中直接運(yùn)行的):

import React, {useState} from 'react';
import { View, Text, Button } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
function HomeScreen({ navigation }) {
  console.log(`home: ${Math.random(new Date().getTime())}`)
  const goToDetail = () => {
    navigation.navigate('Details')
  }
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Home Screen</Text>
      <Button title='Go To detail' onPress={goToDetail}></Button>
    </View>
  )
}
function DetailsScreen({ navigation }) {
  const goHome = () => {
    navigation.navigate('Home')
  }
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Details Screen</Text>
      <Button title='Go Home' onPress={goHome}></Button>
    </View>
  )
}
const Stack = createNativeStackNavigator()
const MemoHomeScreen = React.memo(HomeScreen)
function App() {
  const [age, setAge] = useState(20)
  const homeInst = (props) => (<MemoHomeScreen {...props} />)
  return (
    <NavigationContainer>
      <Stack.Navigator initialRouteName='Home'>
        <Stack.Screen name='Home'>
          {homeInst}
        </Stack.Screen>
        <Stack.Screen name='Details' component={DetailsScreen} />
      </Stack.Navigator>
      <View>
        <Text>{age}</Text>
        <Button title='Increase Age' onPress={() => (setAge(age + 1))}></Button>
      </View>
    </NavigationContainer>
  )
}
export default App;

上面這段代碼的運(yùn)行效果,和使用component props傳遞HomeScreen的運(yùn)行效果一樣。只不過(guò)前者是使用者自己優(yōu)化了重繪,后者是Stack Navigator替你優(yōu)化了。

有因素引起組件更新時(shí),在render callback中使用useCallback

如果我們?cè)偕晕⒍嘞胍幌拢?code>hostInst本質(zhì)上是一個(gè)function,而說(shuō)道function的避免重復(fù)計(jì)算的手段,自然想到了useCallback。我用useCallback來(lái)包裝一下,看看是否能達(dá)到一樣的效果:

const homeInst = useCallback((props) => (<HomeScreen {...props} />), [])

完整代碼如下:

// In App.js in a new project
import React, {useState, useCallback} from 'react'
import { View, Text, Button } from 'react-native'
import { NavigationContainer } from '@react-navigation/native'
import { createNativeStackNavigator } from '@react-navigation/native-stack'
function HomeScreen({ navigation }) {
  console.log(`home: ${Math.random(new Date().getTime())}`)
  const goToDetail = () => {
    navigation.navigate('Details')
  }
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Home Screen</Text>
      <Button title='Go To detail' onPress={goToDetail}></Button>
    </View>
  )
}
function DetailsScreen({ navigation }) {
  const goHome = () => {
    navigation.navigate('Home')
  }
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Details Screen</Text>
      <Button title='Go Home' onPress={goHome}></Button>
    </View>
  )
}
const Stack = createNativeStackNavigator()
function App() {
  const [age, setAge] = useState(20)
  const homeInst = useCallback((props) => (<HomeScreen {...props} />), [])
  return (
    <NavigationContainer>
      <Stack.Navigator initialRouteName='Home'>
        <Stack.Screen name='Home'>
          {homeInst}
        </Stack.Screen>
        <Stack.Screen name='Details' component={DetailsScreen} />
      </Stack.Navigator>
      <View>
        <Text>{age}</Text>
        <Button title='Increase Age' onPress={() => (setAge(age + 1))}></Button>
      </View>
    </NavigationContainer>
  )
}
export default App

我試了一下,效果和使用React.memo是一樣的,都可以達(dá)到避免無(wú)效重復(fù)繪制HomeScreen的目的。

總結(jié)

Stack Navigator的使用,除非特殊情況,非得加extraData,否則強(qiáng)烈推薦用props的方式傳遞組件,減少思維負(fù)擔(dān)。如果要使用render callback,那么我是推薦使用useCallback代替React.memo的,因?yàn)榕浜?code>useCallback的第二個(gè)參數(shù),控制起來(lái)更加有針對(duì)性。

以上就是詳解Stack Navigator中使用自定義的Render Callback的詳細(xì)內(nèi)容,更多關(guān)于Stack Navigator自定義Render Callback的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 使用React實(shí)現(xiàn)輪播效果組件示例代碼

    使用React實(shí)現(xiàn)輪播效果組件示例代碼

    React剛出來(lái)不久,組件還比較少,不像jquery那樣已經(jīng)有很多現(xiàn)成的插件了,于是自己寫(xiě)了一個(gè)基于React的輪播效果組件,現(xiàn)在分享給大家,有需要的可以參考借鑒。
    2016-09-09
  • react 國(guó)際化的實(shí)現(xiàn)代碼示例

    react 國(guó)際化的實(shí)現(xiàn)代碼示例

    這篇文章主要介紹了react 國(guó)際化的實(shí)現(xiàn)代碼示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-09-09
  • React中的for循環(huán)解讀

    React中的for循環(huán)解讀

    這篇文章主要介紹了React中的for循環(huán)解讀,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-01-01
  • React組件創(chuàng)建與事件綁定的實(shí)現(xiàn)方法

    React組件創(chuàng)建與事件綁定的實(shí)現(xiàn)方法

    react事件綁定時(shí)。this并不會(huì)指向當(dāng)前DOM元素。往往使用bind來(lái)改變this指向,今天通過(guò)本文給大家介紹React事件綁定的方式,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧
    2022-12-12
  • React避免不必要的重新渲染的方法示例

    React避免不必要的重新渲染的方法示例

    構(gòu)建高性能?React?應(yīng)用程序的關(guān)鍵之一是避免不必要的重新渲染,React?的渲染引擎是高效的,但防止在不需要的地方重新渲染仍然至關(guān)重要,在這篇文章中,我們將介紹常見(jiàn)錯(cuò)誤以及如何避免它們,需要的朋友可以參考下
    2024-10-10
  • React用法之高階組件的用法詳解

    React用法之高階組件的用法詳解

    高階組件也就是我們常說(shuō)的HOC,是React中用于復(fù)用組件邏輯的一種高級(jí)技巧。這篇文章主要通過(guò)一些示例帶大家學(xué)習(xí)一下高階組件的使用,希望對(duì)大家有所幫助
    2023-04-04
  • 在create-react-app中使用sass的方法示例

    在create-react-app中使用sass的方法示例

    這篇文章主要介紹了在create-react-app中使用sass的方法示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-10-10
  • React深入淺出分析Hooks源碼

    React深入淺出分析Hooks源碼

    在react類組件(class)寫(xiě)法中,有setState和生命周期對(duì)狀態(tài)進(jìn)行管理,但是在函數(shù)組件中不存在這些,故引入hooks(版本:>=16.8),使開(kāi)發(fā)者在非class的情況下使用更多react特性
    2022-11-11
  • react父組件調(diào)用子組件的方式匯總

    react父組件調(diào)用子組件的方式匯總

    在react中常用props實(shí)現(xiàn)子組件數(shù)據(jù)到父組件的傳遞,但是父組件調(diào)用子組件的功能卻不常用,下面這篇文章主要給大家介紹了關(guān)于react父組件調(diào)用子組件的相關(guān)資料,需要的朋友可以參考下
    2022-08-08
  • React為什么需要Scheduler調(diào)度器原理詳解

    React為什么需要Scheduler調(diào)度器原理詳解

    這篇文章主要為大家介紹了React為什么需要Scheduler調(diào)度器原理詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-10-10

最新評(píng)論

定西市| 依安县| 南涧| 类乌齐县| 丘北县| 云安县| 河津市| 年辖:市辖区| 蓬安县| 泽库县| 蛟河市| 平阴县| 武川县| 乐安县| 石城县| 商南县| 高平市| 吕梁市| 建昌县| 临猗县| 绥宁县| 会同县| 北安市| 昌黎县| 托里县| 资中县| 定兴县| 荆州市| 探索| 永寿县| 黄平县| 蓝山县| 南康市| 开封县| 安平县| 四子王旗| 开江县| 开鲁县| 梅河口市| 峨眉山市| 石渠县|