Gay*_*d.P 8 javascript react-native
当我在互联网上搜索react-native优化/最佳实践(特别是FlatLists通常贪婪的优化/最佳实践)时,我总是找到不要使用箭头函数的建议<Component onPress={() => ... }。
示例1: https ://reactnative.dev/docs/optimizing-flatlist-configuration#avoid-anonymous-function-on-renderitem :
\n\n\n将 renderItem 函数移出到 render 函数的外部,这样每次调用 render 函数时它就不会重新创建自己。(...)
\n
示例 2: https: //blog.codemagic.io/improve-react-native-app-performance/:
\n\n\n避免箭头函数:箭头函数是浪费重新渲染的常见罪魁祸首。不要\xe2\x80\x99t 在函数中使用箭头函数作为回调来渲染视图 (...)
\n
示例 3: https: //medium.com/wix-engineering/dealing-with-performance-issues-in-react-native-b181d0012cfa:
\n\n\n箭头函数是浪费重新渲染的另一个常见嫌疑点。不要在渲染函数中使用箭头函数作为回调(例如单击/点击)(...)
\n
据我了解,建议不要使用箭头功能(尤其是在onPress按钮 和中FlatList),并尽可能将组件放在渲染之外。
良好实践示例:
\nconst IndexScreen = () => { \n const onPress = () => console.log(\'PRESS, change state, etc...\')\n\n return (\n <>\n <Button\n onPress={onPress}\n />\n <FlatList\n ...\n renderItem={renderItem}\n ListFooterComponent={renderFooter}\n />\n </>\n )\n}\n\nconst renderItem = ({ item: data }) => <Item data={data} ... />\nconst renderFooter = () => <Footer ... />\n\nexport default IndexScreen\nRun Code Online (Sandbox Code Playgroud)\n但是,通常,我还有其他属性可以集成到我的子组件中。因此箭头函数是强制性的:
\nconst IndexScreen = () => {\n const otherData = ...(usually it comes from a useContext())...\n\n <FlatList\n ...\n renderItem={({ item: data }) => renderItem(data, otherData)}\n />\n}\n\nconst renderItem = (data, otherData) => <Item data={data} otherData={otherData} />\n\nexport default IndexScreen\nRun Code Online (Sandbox Code Playgroud)\n在后一种情况下,尽管存在箭头函数,是否仍遵循良好实践?\n总而言之,如果我删除otherData(为了简单起见),这两种情况是否严格相同并且是否遵循良好实践?
情况一:
\nconst IndexScreen = () => { \n return (\n <FlatList\n ...\n renderItem={renderItem}\n />\n )\n}\n\nconst renderItem = ({ item: data }) => <Item data={data} ... />\n\nexport default IndexScreen\nRun Code Online (Sandbox Code Playgroud)\n=== 情况2?
\nconst IndexScreen = () => { \n return (\n <FlatList\n ...\n renderItem={({ item: data }) => renderItem(data)}\n />\n )\n}\n\nconst renderItem = (data) => <Item data={data} ... />\n\nexport default IndexScreen\nRun Code Online (Sandbox Code Playgroud)\n
win*_*ill 11
答案与箭头函数无关,而是理解引用相等为什么 React 可能决定重新渲染组件。
您可以使用 useCallback 来包装您的函数。这将导致对 renderItem 的引用仅在回调依赖项之一更新时更新。
const renderItem = useCallback(()=>{
...
},
[otherdata]);
Run Code Online (Sandbox Code Playgroud)
第一种情况是理想的,因为当您的应用程序代码运行时,它只会创建一个renderItem函数。在第二种情况下,即使它没有 otherProps,您也没有遵循良好实践,因为此行中的每个渲染都会创建一个新函数
renderItem={({ item: data }) => renderItem(data)}
Run Code Online (Sandbox Code Playgroud)
因此,每次都要重新渲染 FlatList。
renderItem要修复它,您需要记住在prop中传递的函数useCallback
const renderItem = useCallback(({ item: data }) => {
return (<Item data={data} />)
}, []);
...
<FlatList
...
renderItem={renderItem}
/>
Run Code Online (Sandbox Code Playgroud)
因此,记忆版本只会在组件安装时创建一次。而且,如果您需要在渲染函数中注入更多数据,则可以将该数据定义为挂钩的依赖项,useCallback以便仅在数据更改时创建该函数,从而减少树中的重新渲染。
const renderItem = useCallback(({ item: data }) => {
return (<Item data={data} otherData={otherData} />)
}, [otherData]);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1263 次 |
| 最近记录: |