React Native 및 Expo 사용한 목록 디자인 구매.
git clone https://github.com/RafaelR4mos/challenge-react-native-shop-list.git package.json 에 설치하십시오 npm installnpm run startRN 버전에는 아이콘 라이브러리를 사용하십시오.
npm install phosphor-react-native아이콘 사용 :
import { Basket } from 'phosphor-react-native'
export function Componente() {
return (
<Basket
size={32}
color="#FFFFFF"
weight='bold'
/>
)
}
양식화 된 구성 요소 및 테마 사용. 웹 버전의 가장 큰 차이점은 타이핑과 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 다음 코드입니다.
//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 ;
} ;
}
}
} 때때로 우리는 react-navigation 프로그램 페이지간에 정보를 교환해야합니다.
useNavigation() 가져 오기 import { useNavigation } from '@react-navigation/native' ; const navigation = useNavigation ( ) ;navigate 사용합니다 navigation . navigate ( 'route' , { state } ) ; hook useRoute 사용하는 것이 중요하며, 이는 react-navigation 에서도 나옵니다. 이것에서 내부 route.params Params Ideial은 또한 "as" + 팁과 함께 이러한 매개 변수는 무엇입니까?
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 와 유사하지만 비동기식이 다르고 사용할 수있는 패턴이 있습니다.
이 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?