用React Native和Expo採購列表設計。
git clone https://github.com/RafaelR4mos/challenge-react-native-shop-list.git package.json中npm installnpm run start將圖標庫用於RN版本。
npm install phosphor-react-native使用圖標:
import { Basket } from 'phosphor-react-native'
export function Componente() {
return (
<Basket
size={32}
color="#FFFFFF"
weight='bold'
/>
)
}
風格化的組件和主題的使用。 Web版本的最大區別是在RN版本中打字和注意
//styles.ts
import 'styled-components/native' ;
export const Container = styled . View `
color: red;
` ; //tipagem
import 'styled-components/native' ;
import theme from '../theme' ; //caminho do tema
//importante usar o '/native' aqui também.
declare module 'styled-components/native' {
type ThemeType = typeof theme ;
export interface DefaultTheme extends ThemeType { }
} attrs屬性因此,可以消耗應用程序的主題,而不必在.tsx文件本身中進行樣式,我們可以在styles.ts中使用。 ts以下代碼:
//Aqui mudamos os atributos 'size' e 'color' através do arquivo de estilização
export const BackIcon = styled ( CaretLeft ) . attrs ( ( { theme } ) => ( {
size : 32 ,
color : theme . COLORS . WHITE ,
} ) ) `` ;type鍵入聯合如果我們創建個性化組件,並且還必須擴展本機組件的鍵入,則可以將代碼用作基礎:
//Importa tipagem do touchable opacity que vem do RN
import { TouchableOpacityProps } from 'react-native' ;
//Com o caractere '&' adiciona os tipos nativos + o que for definido entre chaves
type GroupCardProps = TouchableOpacityProps & {
title : string ;
} ;當使用許多變量(例如theme , type , variant和其他變量)中,可能只有樣式組件css助手助手有助於簡化語法。
import styled , { css } from 'styled-components/native' ;
//Com isso `theme` não precisa ser desestruturado em todas propriedades.
export const NumbersOfPlayers = styled . Text `
${ ( { theme } ) => css `
color: ${ theme . COLORS . GRAY_200 } ;
font-family: ${ theme . FONT_FAMILY . BOLD } ;
font-size: ${ theme . FONT_SIZE . SM } px;
` } ;
` ;npm install @react-navigation/nativeexpo項目的依賴項npx expo install react-native-screens react-native-safe-area-contextnpm install @react-navigation/native-stackrotas的contexto : routes/app.routes.tsx
import { createNativeStackNavigator } from '@react-navigation/native-stack' ;
import { MyLists } from '../screens/MyyList' ;
const { Navigator , Screen } = createNativeStackNavigator ( ) ;
//Navigator --> Envolve as rotas
//Screen --> Rota individual com nome e apontando para componente
export function AppRoutes ( ) {
return (
< Navigator screenOptions = { { headerShown : false } } >
< Screen
name = "myLists"
component = { MyLists }
/>
</ Navigator >
) ;
}index.tsx
import { NavigationContainer } from '@react-navigation/native' ;
import { useTheme } from 'styled-components/native' ;
import { AppRoutes } from './app.routes' ;
import { View } from 'react-native' ;
export function Routes ( ) {
const { COLORS } = useTheme ( ) ;
//NavigationContainer --> Fornece o contexto de navegação para o app.
// * A estilização da view remove o glitch effect ao trocar de página.
return (
< View style = { { flex : 1 , backgroundColor : COLORS . GRAY_600 } } >
< NavigationContainer >
< AppRoutes />
</ NavigationContainer >
</ View >
) ;
} @types/有趣的是說出我們的應用程序中存在哪些路線,尤其是在每種路線上都期望哪些params
創建navigation.d.ts文件
重寫文件中的模塊
export declare global {
namespace ReactNavigation {
interface RootParamList {
myLists : undefined ;
newList : undefined ;
list : {
listName : string ;
} ;
}
}
} 有時我們需要在應用程序頁面之間交換信息,為此,我們可以使用lib react-navigation和他的鉤子
useNavigation() import { useNavigation } from '@react-navigation/native' ; const navigation = useNavigation ( ) ;navigate navigation . navigate ( 'route' , { state } ) ;使用掛鉤useRoute ,這也很重要,這也來自react-navigation 。在此,可以從內部route.params參數意識形態也是tiar,這些參數是什麼參數
const route = useRoute ( ) ;
const { param } = route . params as RouteParams ; useFocusEffect將重點放在頁面上useFocusEffect與useEffect非常相似,但是每當頁面接收到焦點時,它都會激活,即,除了第一個加載,如果導航到頁面上,則會被調用。
進口:
import { useFocusEffect } from '@react-navigation/native' ;使用:
useFocusEffect (
useCallback ( ( ) => {
fetchLists ( ) ;
} , [ ] )
) ;
useCallBack一起用於避免啟動不必要的渲染,這可以幫助您進行應用程序性能。
類似於瀏覽器位置。它可以幫助解決prop-drilling問題,因為它集中了一個地方。
安裝:
npx expo instal @react-native-async-storage/async-storage
處理AsyncStorage的動力學,類似於localstorage,但是異步是不同的,並且可以使用一種模式。
僅用於此storage的文件夾
創建storageConfig.ts文件以定義存儲鍵
這樣,我們保證在保存在AsyncStorage中的元素的鑰匙中維護更好
const LIST_COLLECTION = '@shop-list:lists' ;
const ITEM_COLLECTION = '@shop-list:items' ;
export { LIST_COLLECTION , ITEM_COLLECTION } ;示例:播放器
檔案:
| - 清單| ListCreate.ts | ListDelete.ts | ListGetall.ts | ListGetSingle.ts
import AsyncStorage from '@react-native-async-storage/async-storage' ;
import { LIST_COLLECTION } from '../storageConfig' ;
import { ShoppingList } from '../../screens/Lists' ;
import { listsGetAll } from './listGetAll' ;
import { AppError } from '../../utils/AppError' ;
export async function listCreate ( newList : ShoppingList ) {
try {
const storedLists = await listsGetAll ( ) ;
const listAlreadyExists = storedLists
. map ( ( item : ShoppingList ) => item . title )
. includes ( newList . title ) ;
if ( listAlreadyExists ) {
throw new AppError ( 'Já existe uma lista com este nome.' ) ;
}
const newStorage = JSON . stringify ( [ ... storedLists , newList ] ) ;
await AsyncStorage . setItem ( LIST_COLLECTION , newStorage ) ;
console . log ( storedLists ) ;
} catch ( error ) {
throw error ;
}
}useRef()處理元素我們可以使用Hook Useref()訪問元素的引用,從而處理focus() , blur()等。
示例:通過提交表單,我們可以在輸入元素中使用blur() ,畢竟,用戶已經輸入了所需的內容,因此desfoque效果可以結束打開的鍵盤並將焦點刪除到輸入中。
//Criação da referência de vinculação
const newListNameInputRef = useRef < TextInput > ( null ) ;
function handleSubmit ( ) {
///...
//Desfoca o elemento
newListNameInputRef . current ?. blur ( ) ;
}
//IMPORTANTE adicionar o `ref` ao elemento, caso seja um componente é necessário enviar via prop.
return (
< View >
< Input
inputRef = { newListNameInputRef }
onChangeText = { setNewListName }
value = { newListName }
placeholder = "Nome da sua lista"
autoCorrect = { false }
onSubmitEditing = { handleAddList }
returnKeyType = "done"
/ >
< / View >
) ;因此,我們可以區分throw的通用/未知錯誤和我們的應用程序識別的錯誤,我們可以創建一個具有message屬性的類並實例化此類,因此我們可以在catch塊中收集instaceof <classe> 。
例子:
export class AppError {
message : string ;
constructor ( message : string ) {
this . message = message ;
}
} throw new AppError ( 'Estas lista já esta adicionada!' ) ; catch ( error ) {
if ( error instanceof AppError ) {
Alert . alert ( 'Nova lista' , error . message ) ;
} else {
Alert . alert ( 'Nova lista' , 'Não foi possível adicionar' ) ;
console . error ( error ) ;
}
}作者:拉斐爾·拉莫斯(Rafael Ramos)?