如果您是一位初學者或有經驗的 React Native 開發者,那麼您必須了解代碼實踐是一項不可妥協的技能。作為一名開發者,交付項目是必須的,但編寫可擴展且高品質的代碼將有助於您和您的團隊未來的發展。
在我們繼續之前,這些實踐可以應用於 React Native CLI 或 Expo 項目。根據 RN 團隊的說法,從 2024 年起,Expo 將成為構建 React Native 項目的官方框架。
在這篇文章中,我們將學習有關 React Native 項目的代碼實踐。請記住,一個好的項目是以下幾點的平衡:
可擴展性
一致性
可維護性
可讀性
閱讀我關於如何作為 ReactJS 開發者開始學習 React Native 的博客。
開發者最重要的事情之一是擁有一個可維護、可讀、可擴展的代碼庫。您的項目結構會對未來的開發者有所幫助。使用 Expo 時,項目的結構有一定的規範,但作為一名 React Native 開發者,根據您的項目,您應該計劃項目的結構:
my-app/
├── assets/
│ ├── fonts/
│ ├── images/
│ └── icons/
├── components/
│ ├── Button.js
│ ├── Button.styles.js
│ └── Header.js
├── screens/
│ ├── HomeScreen/
│ │ ├── HomeScreen.js
│ │ └── HomeScreen.styles.js
│ └── ProfileScreen/
│ ├── ProfileScreen.js
│ └── ProfileScreen.styles.js
├── navigation/
│ ├── AppNavigator.js
│ ├── AuthNavigator.js
│ └── MainNavigator.js
├── redux/ (或 store/ 如果使用 Zustand、MobX 等)
│ ├── actions/
│ ├── reducers/
│ ├── store.js
│ └── types.js
├── services/
│ ├── api.js
│ └── auth.js
├── utils/
│ ├── helpers.js
│ └── constants.js
├── App.js
├── package.json
├── .babelrc
└── README.md
更新:請根據您的需求探索特定領域或 功能 的架構。感謝 B Camphart 和 Idris Gadi。
冗長的導入路徑可能會使您的代碼變得難以閱讀和維護。與其編寫像 ../../../components/Button
這樣的冗長相對路徑,不如使用別名來縮短它們,讓您的代碼更加可讀。
import Button from 'components/ui/Button';
import Header from 'components/layout/Header';
要自動管理導入的順序,可以使用 Babel 的插件來處理這個問題。這樣可以保持導入的整潔,減少手動干預。
npm install --save-dev babel-plugin-module-resolver
在選擇 TypeScript (TS) 和 JavaScript (JS) 時,幾乎沒有爭議,尤其是對於大型應用。TypeScript 提供靜態類型檢查,有助於在編譯時而非運行時捕獲錯誤,從而產生更可靠和易於維護的代碼。
有多種方式可以為 RN 項目進行樣式設置。可以使用 NativeWind 或 React Native 的 styled。面對如此多的選擇,應選擇一致性、可擴展性和可維護性。閱讀我關於樣式設置的博客 這裡。
1. inline: 這對於大型項目來說並不是一個好的選擇。
<View style={{ backgroundColor: 'blue', padding: 10 }}>
<Text style={{ color: 'white' }}>Hello</Text>
</View>
2. StyleSheet API: 這樣做不錯,但樣式無法重用。
import { StyleSheet, View, Text } from 'react-native';
const styles = StyleSheet.create({
container: {
backgroundColor: 'blue',
padding: 10,
},
text: {
color: 'white',
},
});
const App = () => (
<View style={styles.container}>
<Text style={styles.text}>Hello</Text>
</View>
);
3. 分開樣式: 這是我對大型項目的首選樣式方式。創建一個單獨的 style.js
並在需要的組件中使用它。
/components
├── MyComponent.js
├── MyComponent.styles.js
/App.js
// MyComponent.styles.js
import { StyleSheet } from 'react-native';
export default StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#f5f5f5',
},
title: {
fontSize: 24,
fontWeight: 'bold',
color: '#333',
marginBottom: 20,
},
button: {
backgroundColor: '#007bff',
paddingVertical: 10,
paddingHorizontal: 20,
borderRadius: 5,
},
buttonText: {
color: '#fff',
fontSize: 16,
fontWeight: '600',
},
});
// MyComponent.js
import React from 'react';
import { View, Text, Pressable } from 'react-native';
import styles from './MyComponent.styles';
const MyComponent = () => {
return (
<View style={styles.container}>
<Text style={styles.title}>Hello from MyComponent</Text>
<Pressable style={styles.button}>
<Text style={styles.buttonText}>Click Me</Text>
</Pressable>
</View>
);
};
export default MyComponent;
4. styled components: 對於大型項目來說,這是另一種方式。
更新:請查看 這裡。
顯然,Styled Components 存在性能問題: https://github.com/styled-components/styled-components/issues/3940。
import styled from 'styled-components/native';
const Container = styled.View`
background-color: blue;
padding: 10px;
`;
const StyledText = styled.Text`
color: white;
`;
const App = () => (
<Container>
<StyledText>Hello</StyledText>
</Container>
);
5. NativeWind: NativeWind 是一種很好的樣式設置方式。在安裝了 NativeWind 之後,您可以使用類來為應用程式設置樣式。通過這樣,您將樣式工作委派出去。
import React from 'react';
import { View, Text, Pressable } from 'react-native';
import { styled } from 'nativewind';
const App = () => {
return (
<View className="flex-1 justify-center items-center bg-gray-100">
<Text className="text-2xl font-bold text-blue-500 mb-4">
歡迎來到 NativeWind!
</Text>
<Pressable className="bg-blue-500 px-4 py-2 rounded">
<Text className="text-white font-semibold">按我</Text>
</Pressable>
</View>
);
};
export default App;
Props 用於在 React Native 中的組件之間進行通信,允許數據從父組件流向子組件。就像樣式設置一樣,管理 props 有多種方法。一致性是關鍵,因此建議在整個項目中堅持一種方法。
此外,始終進行 props 的解構,可以使代碼更乾淨、更易讀。解構不僅提高了可讀性,而且還更容易查看一個組件使用了哪些 props。
const MyComponent = ({ title, subtitle }) => {
return (
<View>
<Text>{title}</Text>
<Text>{subtitle}</Text>
</View>
);
};
有效的狀態管理確保了隨著代碼庫的增長,應用程序仍然能保持性能和可管理性。在當今的時代,我們有很多選擇來選擇最佳的狀態管理。
a. 優先考慮局部狀態而非全局狀態。
b. 對於簡單狀態,使用 Context API
。
c. 對於複雜狀態,使用狀態管理庫。
d. 不可變狀態更新。
e. 優先考慮 redux toolkit
而非 redux
。
import { createSlice } from '@reduxjs/toolkit';
const booksSlice = createSlice({
name: 'books',
initialState: [],
reducers: {
addBook: (state, action) => {
state.push(action.payload);
},
removeBook: (state, action) => {
return state.filter(book => book.id !== action.payload);
},
},
});
export const { addBook, removeBook } = booksSlice.actions;
export default booksSlice.reducer;
為了確保應用程序的健康和減少崩潰,實施崩潰分析和錯誤追蹤是至關重要的:
a. 使用崩潰分析工具:實施如 Firebase Crashlytics
或 Sentry
的服務。
b. 測試應用程序的穩定性
運行自動化測試和手動壓力測試,以捕獲邊緣案例崩潰。利用 TestFlight 或 Google Play Beta Testing 這樣的服務。
您可以追蹤本地崩潰(iOS/Android)和 JavaScript 錯誤。使用 ErrorBoundary 捕獲 JavaScript 錯誤並將其登錄到崩潰分析服務中。
c. 跟踪 JS 和本地錯誤
import React from 'react';
import * as Sentry from '@sentry/react-native';
class ErrorBoundary extends React.Component {
componentDidCatch(error, errorInfo) {
Sentry.captureException(error, { extra: errorInfo });
}
render() {
if (this.state.hasError) {
return <Text>出錯了。</Text>;
}
return this.props.children;
}
}
紀錄有助於追踪應用程序行為、調試問題和收集分析資料。
a. 使用紀錄框架
React Native Logger:專為 React Native 設計的易用紀錄器。
Winston:一個多傳輸的紀錄庫,可以與 React Native 和 Node.js 一起使用。
import logger from 'react-native-logger';
logger.log('這是一條調試日志');
logger.warn('這是一條警告日志');
logger.error('這是一條錯誤日志');
b. 不同的日誌等級
使用適當的日誌等級,如 debug
、info
、warn
和 error
。
在生產環境中,通過僅允許錯誤和警告日誌來減少日誌的詳細程度,而在開發模式中,使用調試和信息。
c. 遠程紀錄
考慮將日誌發送到遠程紀錄服務,例如:
Papertrail
Loggly
Firebase Analytics
d. 小心紀錄敏感信息
避免紀錄敏感的用戶信息,如密碼、令牌或個人數據。
每個項目的測試都是至關重要的。作為一名開發者,質量是開發者的責任。在 React Native 世界中,有:
單元測試
集成測試
端到端測試
至少要花些時間在端到端測試上。有許多工具可供測試使用。
祝學習愉快!!
原文出處:https://dev.to/hellonehha/react-native-code-practices-6dl