- Primeiros passos no React Native - Aula 1 | Curso React Native (aprendiz) | Onebitcode
É uma ferramenta de app em react.
npm install --global expo-cli
expo init "nome do projeto" ou yarn create react-native-app "nome do arquivo"
- cd my-project
- yarn start # you can open iOS, Android, or web from here, or run them directly with the commands below.
- yarn android
- yarn ios # requires an iOS device or macOS for access to an iOS simulator
- yarn web
- expo start --tunnel # executa
npx expo install expo-updates
npx pod-install
expo build:android -t apk
expo build:ios -t apk
ou
npm install -g eas-cli
eas build -p android
Entre no seguinte site Ape Tools para gerar ambos.
{
"expo": {
"name": "Campo Minado",
"slug": "Campo Minado",
"icon": "./icone/calculadora.png",
"version": "1.0.0",
"platforms": [
"ios",
"android"
],
"splash": {
"resizeMode": "contain"
},
"android": {
"package": "com.jeovane.campo_minado",
"versionCode": 1
}
}
}
Várias orientações de tela devem funcionar bem por padrão, a menos que você esteja usando a DimensionsAPI e não manipule alterações de orientação. Se você não quiser oferecer suporte a várias orientações de tela, poderá bloquear a orientação da tela para retrato ou paisagem.
No iOS, na guia Geral e na seção Informações de implantação do Xcode, habilite a Orientação do dispositivo que você deseja oferecer suporte (certifique-se de ter selecionado o iPhone no menu Dispositivos ao fazer as alterações). Para Android, abra o arquivo AndroidManifest.xml e, dentro do elemento activity, adicione
'android:screenOrientation="portrait"'
para travar em retrato ou
'android:screenOrientation="landscape"'
para travar em paisagem.
Uma outra alternativa é seguir a documentação do expo.
No termina do seu projeto execute.
npx expo install expo-screen-orientation
Agora no index.js ou index.tsx importe.
import * as ScreenOrientation from 'expo-screen-orientation';
Adicione a seguinte função.
async function changeScreenOrientation() {
await ScreenOrientation.lockAsync(ScreenOrientation.OrientationLock.PORTRAIT);
}
E chame ela antes do regiterRootComponent(App).
changeScreenOrientation()
Expo - Adicionando uma tela inicial e ícones
Adicionando uma splash screen no React Native
Criar o tsconfig.json e coloque essas linhas nele:
{
"extends": "expo/tsconfig.base",
"compilerOptions": {
"experimentalDecorators": true,
"forceConsistentCasingInFileNames": true,
"isolatedModules": true,
"lib": ["ESNext"],
"noEmitHelpers": true,
"noFallthroughCasesInSwitch": true,
"noImplicitReturns": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"strict": true
}
}
yarn add @types/react -D
yarn add @types/react-native -D
yarn add ts-node -D
yarn add typescript -D
ou
yarn add @types/react @types/react-native ts-node typescript -D
yarn add expo-updates
yarn add @expo/webpack-config
ou
yarn add expo-updates @expo/webpack-config
yarn add styled-components
yarn add @types/styled-components-react-native
No packege.json do projeto altere o main de "main":"index.js" para "main": "./src/index.tsx"
expo start --tunnel # executa
yarn add react-native-svg @fortawesome/fontawesome-svg-core @fortawesome/free-solid-svg-icons @fortawesome/react-native-fontawesome
yarn add @fortawesome/free-brands-svg-icons
yarn add @fortawesome/free-regular-svg-icons
@fortawesome/react-native-fontawesome
npx expo install react-native-svg
Erro while updating property fill of a view managed by: RNSVGPath
Instale o seguinte pacote:
yarn add react-native-svg@9.13.3
Motivo: A partir de 17 de fevereiro de 2020, a instalação da versão 9.13.3 do react-native-svg resolverá seu problema.
Aparentemente, usar a CLI de instalação do expo instalará a versão mais recente deste pacote, mas isso causará um erro ao iniciar o projeto (você verá que especificou qual versão do pacote é suportada pelo expo).
Invariant Violation: requireNativeComponent: "RNSVGSvgViewAndroid" was not found in the UIManager.
Instale a seguinte verção do react-native-svg
"react-native-svg": "13.4.0"
Nesse link tem varias alternativas link
Para mim o que deeu certo foi envolver o Swipeable em um GestureHandlerRootView.
Pecistencia dos dados.
Instale o seguinte modulo, pois a versão do react-native está depreciada e do Obs: react-native-community/async-storage está descomtinuado.
yarn add @react-native-async-storage/async-storage
npx expo install @react-native-async-storage/async-storage - só se estiver usando o expo
Para todas as telas
<Stack.Navigator
screenOptions={{
headerShown: false
}}
>
<Stack.Screen name="route-name" component={ScreenComponent} />
</Stack.Navigator>
Se você deseja apenas ocultar o cabeçalho em 1 tela, pode fazer isso definindo screenOptions no componente de tela, veja abaixo, por exemplo:
<Stack.Navigator
screenOptions={{
headerShown: false
}}
>
<Stack.Screen name="route-name" component={ScreenComponent} />
<Stack.Screen options={{headerShown: false}} name="route-name" component={ScreenComponent} />
</Stack.Navigator>
<View style={styles.container}>
<Lightbox>
<Image
style={{ height: 300, width: 300 }}
source={{
uri: 'http://knittingisawesome.com/wp-content/uploads/2012/12/cat-wearing-a-reindeer-hat1.jpg',
}}
/>
</Lightbox>
</View>
Invariant Violation: ViewPropTypes has been removed from React Native. Migrate to ViewPropTypes exported from 'deprecated-react-native-prop-types'.
- npm install deprecated-react-native-prop-types
- em node_modules/react-native/index.js substitua da linha 436 até 464
// Deprecated Prop Types
get ColorPropType(): $FlowFixMe {
return require('deprecated-react-native-prop-types').ColorPropType
},
get EdgeInsetsPropType(): $FlowFixMe {
return require('deprecated-react-native-prop-types').EdgeInsetsPropType
},
get PointPropType(): $FlowFixMe {
return require('deprecated-react-native-prop-types').PointPropType
},
get ViewPropTypes(): $FlowFixMe {
return require('deprecated-react-native-prop-types').ViewPropTypes
},
- apos execute npx patch-package react-native
<Text
style={styles.hyperlinkStyle}
onPress={() => {
Linking.openURL('https://reactnative.dev');
}}>
Site Oficial do React Native
</Text>
const { width } = Dimensions.get('window');
const SPACING = 10;
const THUMB_SIZE = 70;
const [indexSelected, setIndexSelected] = useState(0);
const onSelect = (indexSelected: number) => {
setIndexSelected(indexSelected);
};
const onScrollEnd = (e: { nativeEvent: { contentOffset: any; layoutMeasurement: any; }; }) => {
const contentOffset = e.nativeEvent.contentOffset;
const viewSize = e.nativeEvent.layoutMeasurement;
// Divide the horizontal offset by the width of the view to see which page is visible
const pageNum = Math.floor(contentOffset.x / viewSize.width);
onSelect(pageNum)
}
return (
<>
<FlatList
horizontal
data={images}
pagingEnabled
style={{ marginLeft: -10, }}
showsHorizontalScrollIndicator={false}
contentContainerStyle={{
paddingHorizontal: SPACING
}}
keyExtractor={(item) => item.data}
onMomentumScrollEnd={onScrollEnd}
//
renderItem={({ item}) => (
<Image
style={{
width: width + 8,
height: width,
}}
source={{ uri: item.data }}
/>
)
}
/>
<View
style={{
marginTop: 25,
paddingHorizontal: 32,
alignSelf: 'flex-end',
position: "absolute",
// position: "relative",
borderRadius: 10,
justifyContent: "center",
alignItems: "center"
}}
>
<Text
style={{
color: '#fff',
fontSize: 18,
backgroundColor: "#cccccc2b",
marginTop: 105,
width: 60,
textAlign: "center",
borderRadius: 10,
}}
>
{indexSelected + 1}/{images.length}
</Text>
</View>
</>
)
Ao usar o FlatList dentro de uma componente ScrollView pode acarretar o seguinte erro:
ERROR VirtualizedLists should never be nested inside plain ScrollViews with the same orientation
because it can break windowing and other functionality - use another VirtualizedList-backed container instead.
Caso isso aconteça a melhor aternativa possa ser o uso do map em vez do FlatList. Esse erro ocorre pois o FlatList possui um ScrollViews na sua composição e o React Native não aceita muito bem isso.
-
Instale o
npx expo install expo-application
-
Depois entre no link das credenciais
-
Existem 4 tipos diferentes de IDs de cliente que você pode fornecer:
- expoClientId: ID do cliente proxy para uso na Expo Go em iOS e Android.
- iosClientId: ID do cliente nativo do iOS para uso em fluxo de trabalho autônomo e básico.
- androidClientId: ID do cliente nativo do Android para uso em fluxo de trabalho simples e autônomo.
- webClientId: Expo web client ID para uso no navegador.
-
expoClientId: na pagina de credenciais crie um projeto depois celecione o seu perojeto e click em credenciais, assim no tompo selecione criar credenciais e click em OAuth client ID, apos isso você precisa configura a tela de consentimento. Apos isso resolvido, selecione em Application type a opção Web application.
- No campo name coloque Expo Go Proxy
- URIs (origens JavaScript autorizadas): https://auth.expo.io
- URIs de redirecionamento autorizados : https://auth.expo.io/@your-username/your-project-slug
-
iosClientId: faça o mesmo processo do expoClientId só que em Application type selecione IOS em name coloque o nome que form mais conveniente e no campo Bundle ID coloque ex:
host.exp.exponent
. -
androidClientId:faça o mesmo processo do expoClientId só que em Application type selecione Android em name coloque o nome que form mais conveniente e no campo Package name coloque o id gerado do iosClientId. Agora no terminal do projeto diite
openssl rand -base64 32 | openssl sha1 -c
isso ira gera um código, copio e coloque no campo SHA-1 certificate ...
https://graph.facebook.com/me?fields=id,email&access_token=${accessToken}
{
"email": "funlano@email.com",
"id": "id",
}
const images = {
logo: {
uri: require('your-image-path/logo.png')
},
banner: {
uri: require('your-image-path/banner.png')
}
}
export { images };
//YourComponent.js
import { images } from 'yourImagesPath';
// for this test, expected to return [ { name: logo }, { name: banner} ]
const imagesFromTheServer = (your fetch);
imagesFromTheServer.map(image => {
if (!images[image]) {
return <Text>Image not found</Text>;
}
return <Image source={images[image].uri} />; // if image = logo, it will return images[logo] containing the require path as `uri` key
});
import React from 'react';
import {ActivityIndicator, StyleSheet, View} from 'react-native';
const App = () => (
<View style={[styles.container, styles.horizontal]}>
<ActivityIndicator />
<ActivityIndicator size="large" />
<ActivityIndicator size="small" color="#0000ff" />
<ActivityIndicator size="large" color="#00ff00" />
</View>
);
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
},
horizontal: {
flexDirection: 'row',
justifyContent: 'space-around',
padding: 10,
},
});
export default App;
import React, { useState, useCallback, useRef } from "react";
import { Button, View, Alert } from "react-native";
import YoutubePlayer from "react-native-youtube-iframe";
export default function App() {
const [playing, setPlaying] = useState(false);
const onStateChange = useCallback((state) => {
if (state === "ended") {
setPlaying(false);
Alert.alert("video has finished playing!");
}
}, []);
const togglePlaying = useCallback(() => {
setPlaying((prev) => !prev);
}, []);
return (
<View>
<YoutubePlayer
height={300}
play={playing}
videoId={"iee2TATGMyI"}
onChangeState={onStateChange}
/>
<Button title={playing ? "pause" : "play"} onPress={togglePlaying} />
</View>
);
}
No proprio react native existe o useWindowDimensions
import { useWindowDimensions } from "react-native";
const { width } = useWindowDimensions();
Também do react native existe outra opção
import { Dimensions } from "react-native";
const { width } = Dimensions.get("window");
Crie um pasta assets e coloque seu arquivo nela.E no arquivo metro.config.js cole o seguinte código.
// Learn more https://docs.expo.io/guides/customizing-metro
const { getDefaultConfig } = require("expo/metro-config");
module.exports = (async () => {
const {
resolver: { sourceExts, assetExts },
} = await getDefaultConfig(__dirname);
return {
transformer: {
babelTransformerPath: require.resolve("react-native-svg-transformer"),
getTransformOptions: async () => ({
transform: {
experimentalImportSupport: false,
inlineRequires: false,
},
}),
},
resolver: {
assetExts: assetExts.filter((ext) => ext !== "svg"),
sourceExts: [...sourceExts, "svg"],
},
};
})();
Depois instale o seguinte pagete
npm i react-native-svg-transformer
Na raiz do projeto crie um arquivo .svgrrc e cole o seguinte codigo dendro
"replaceAttrValues": {
"#000": "{props.fill}",
"#fff": "{props.stroke}"
}
}
Tambem na raiz do projeto crie um arquivo custom.d.ts e cole o seguinte código dentro
declare module "*.svg" {
const content: React.FunctionComponent<React.SVGAttributes<SVGElement>>;
export default content;
}
Depois importe onde deseja a imagem
import Svg1 from "caminho_da_imagem/nome.svg";
<Svg1
width={25}
height={25}
stroke={"red"}
/>
bottom-sheet-preview.mp4
- Passo 1: instale o pacote react-native-gesture-handler e o importe no aruivo App e envolva com o GestureHandlerRootView
...
import { GestureHandlerRootView } from "react-native-gesture-handler";
export default function App() {
...
<GestureHandlerRootView style={{ flex: 1 }}>
....
</GestureHandlerRootView>
...
}
- Passo 2: Instale o @gorhom/bottom-sheet e o importe onte você quer usar o modal
...
import {
BottomSheetBackdrop,
BottomSheetBackdropProps,
BottomSheetModal,
BottomSheetModalProvider,
} from "@gorhom/bottom-sheet";
const Backdrop = (props: BottomSheetBackdropProps) => {
return <BottomSheetBackdrop {...props} disappearsOnIndex={-1} />;
};
...
const snapPoints = useMemo(() => [550], []);
return return (
<BottomSheetModalProvider>
<BottomSheetModal
onDismiss={()=>{}}
detached
handleIndicatorStyle={{estilo}}
style={{estilo}}
enableDismissOnClose
backdropComponent={Backdrop}
ref={ref}
index={0}
keyboardBlurBehavior="restore"
snapPoints={snapPoints}
>
...
</BottomSheetModal>
</BottomSheetModalProvider>
...