dezembro 21, 2025
18 min de leitura

Perguntas de entrevista React Native sênior com respostas

interview
career-advice
job-search
Perguntas de entrevista React Native sênior com respostas
Milad Bonakdar

Milad Bonakdar

Autor

Prepare-se para entrevistas sênior de React Native com perguntas sobre arquitetura, desempenho do FlatList, módulos nativos, estado, testes e decisões de produção.


Introdução

Entrevistas sênior de React Native costumam avaliar muito mais que sintaxe. Espere perguntas sobre arquitetura de app, profiling de desempenho, integração nativa, limites entre estado e dados, estratégia de testes, qualidade de releases e como você explica trade-offs com restrições reais de produto.

Use este guia para praticar respostas claras de nível sênior. Comece com a decisão que você tomaria e depois explique o raciocínio, o risco e o plano alternativo. Por exemplo, não diga apenas que FlatList pode ser otimizado; explique como você investigaria áreas em branco, batches de renderização, linhas memoizadas, chaves estáveis e mudanças de design quando alturas fixas ou imagens pesadas são o problema real.


React e Hooks Avançados (5 Perguntas)

1. Explique useMemo e useCallback. Quando você deve usá-los?

Resposta: Ambos os hooks otimizam o desempenho memorizando valores/funções.

  • useMemo: Memoriza valores computados (cálculos caros)
  • useCallback: Memoriza referências de função (evita a recriação)
  • Quando usar: Apenas quando você tiver problemas de desempenho. A otimização prematura pode tornar o código mais difícil de ler.
import { useMemo, useCallback, useState } from 'react';

function ExpensiveComponent({ items, onItemClick }) {
  // useMemo - memoriza cálculo caro
  const sortedItems = useMemo(() => {
    console.log('Sorting items...');
    return items.sort((a, b) => a.price - b.price);
  }, [items]); // Recalcula apenas quando os itens mudam
  
  // useCallback - memoriza função
  const handleClick = useCallback((id) => {
    console.log('Item clicked:', id);
    onItemClick(id);
  }, [onItemClick]); // Recria apenas quando onItemClick muda
  
  return (
    <FlatList
      data={sortedItems}
      renderItem={({ item }) => (
        <ItemRow item={item} onClick={handleClick} />
      )}
    />
  );
}

// Componente filho com React.memo
const ItemRow = React.memo(({ item, onClick }) => {
  console.log('Rendering item:', item.id);
  return (
    <TouchableOpacity onPress={() => onClick(item.id)}>
      <Text>{item.name}</Text>
    </TouchableOpacity>
  );
});

Raridade: Muito Comum Dificuldade: Média


2. O que é useRef e quais são seus casos de uso?

Resposta: useRef cria uma referência mutável que persiste entre renderizações sem causar novas renderizações.

  • Casos de Uso:
    • Acessar elementos DOM/nativos
    • Armazenar valores mutáveis sem disparar nova renderização
    • Manter valores anteriores
    • Armazenar timers/intervalos
import { useRef, useEffect } from 'react';
import { TextInput, Animated } from 'react-native';

function FormComponent() {
  const inputRef = useRef(null);
  const previousValue = useRef('');
  const animatedValue = useRef(new Animated.Value(0)).current;
  
  useEffect(() => {
    // Foca o input ao montar
    inputRef.current?.focus();
  }, []);
  
  const handleChange = (text) => {
    console.log('Previous:', previousValue.current);
    console.log('Current:', text);
    previousValue.current = text;
  };
  
  const startAnimation = () => {
    Animated.timing(animatedValue, {
      toValue: 1,
      duration: 300,
      useNativeDriver: true,
    }).start();
  };
  
  return (
    <View>
      <TextInput ref={inputRef} onChangeText={handleChange} />
      <Animated.View style={{ opacity: animatedValue }}>
        <Text>Animated Content</Text>
      </Animated.View>
    </View>
  );
}

// Exemplo de Timer
function Timer() {
  const intervalRef = useRef(null);
  const [count, setCount] = useState(0);
  
  useEffect(() => {
    intervalRef.current = setInterval(() => {
      setCount(c => c + 1);
    }, 1000);
    
    return () => clearInterval(intervalRef.current);
  }, []);
  
  return <Text>{count}</Text>;
}

Raridade: Comum Dificuldade: Média


3. Explique Hooks Personalizados e quando criá-los.

Resposta: Hooks personalizados extraem lógica stateful reutilizável em funções separadas.

  • Benefícios: Reutilização de código, separação de preocupações, teste mais fácil
  • Convenção: Deve começar com "use"
// Hook personalizado para buscar dados da API
function useFetch(url) {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);
  
  useEffect(() => {
    const fetchData = async () => {
      try {
        const response = await fetch(url);
        const json = await response.json();
        setData(json);
      } catch (err) {
        setError(err.message);
      } finally {
        setLoading(false);
      }
    };
    
    fetchData();
  }, [url]);
  
  return { data, loading, error };
}

// Hook personalizado para manipulação de formulário
function useForm(initialValues) {
  const [values, setValues] = useState(initialValues);
  const [errors, setErrors] = useState({});
  
  const handleChange = (name, value) => {
    setValues(prev => ({ ...prev, [name]: value }));
  };
  
  const validate = (validationRules) => {
    const newErrors = {};
    Object.keys(validationRules).forEach(field => {
      const rule = validationRules[field];
      if (rule.required && !values[field]) {
        newErrors[field] = `${field} is required`;
      }
    });
    setErrors(newErrors);
    return Object.keys(newErrors).length === 0;
  };
  
  return { values, errors, handleChange, validate };
}

// Uso
function UserProfile() {
  const { data, loading, error } = useFetch('https://api.example.com/user');
  const { values, errors, handleChange, validate } = useForm({
    name: '',
    email: '',
  });
  
  if (loading) return <ActivityIndicator />;
  if (error) return <Text>Error: {error}</Text>;
  
  return <Text>{data.name}</Text>;
}

Raridade: Comum Dificuldade: Média


4. O que é React Context e quando você deve usá-lo?

Resposta: O Context fornece uma maneira de passar dados pela árvore de componentes sem prop drilling.

  • Casos de Uso: Tema, autenticação, preferências de idioma
  • Cuidado: Pode causar renderizações desnecessárias se não for usado com cuidado
import { createContext, useContext, useState } from 'react';

// Cria contexto
const ThemeContext = createContext();
const AuthContext = createContext();

// Provedor de Tema
function ThemeProvider({ children }) {
  const [theme, setTheme] = useState('light');
  
  const toggleTheme = () => {
    setTheme(prev => prev === 'light' ? 'dark' : 'light');
  };
  
  return (
    <ThemeContext.Provider value={{ theme, toggleTheme }}>
      {children}
    </ThemeContext.Provider>
  );
}

// Provedor de Autenticação
function AuthProvider({ children }) {
  const [user, setUser] = useState(null);
  
  const login = async (credentials) => {
    const user = await loginAPI(credentials);
    setUser(user);
  };
  
  const logout = () => {
    setUser(null);
  };
  
  return (
    <AuthContext.Provider value={{ user, login, logout }}>
      {children}
    </AuthContext.Provider>
  );
}

// Hooks personalizados para contexto
function useTheme() {
  const context = useContext(ThemeContext);
  if (!context) {
    throw new Error('useTheme must be used within ThemeProvider');
  }
  return context;
}

function useAuth() {
  return useContext(AuthContext);
}

// Uso
function App() {
  return (
    <ThemeProvider>
      <AuthProvider>
        <MainApp />
      </AuthProvider>
    </ThemeProvider>
  );
}

function ThemedButton() {
  const { theme, toggleTheme } = useTheme();
  const { user } = useAuth();
  
  return (
    <TouchableOpacity
      style={{ backgroundColor: theme === 'light' ? '#fff' : '#333' }}
      onPress={toggleTheme}
    >
      <Text>{user ? `Hello, ${user.name}` : 'Guest'}</Text>
    </TouchableOpacity>
  );
}

Raridade: Muito Comum Dificuldade: Média


5. Explique a diferença entre useEffect e useLayoutEffect.

Resposta: Ambos executam side effects, mas em momentos diferentes:

  • useEffect: Executa assincronamente após a renderização ser pintada na tela
  • useLayoutEffect: Executa sincronamente antes de pintar (bloqueia atualizações visuais)
  • Use useLayoutEffect quando: Você precisa medir o DOM ou evitar flicker visual
import { useEffect, useLayoutEffect, useRef, useState } from 'react';

function MeasureComponent() {
  const [height, setHeight] = useState(0);
  const elementRef = useRef(null);
  
  // useLayoutEffect - mede antes de pintar
  useLayoutEffect(() => {
    if (elementRef.current) {
      const { height } = elementRef.current.measure((x, y, width, height) => {
        setHeight(height);
      });
    }
  }, []);
  
  // useEffect - depois de pintar
  useEffect(() => {
    console.log('Component rendered');
  }, []);
  
  return (
    <View ref={elementRef}>
      <Text>Height: {height}</Text>
    </View>
  );
}

Raridade: Média Dificuldade: Difícil


Gerenciamento de Estado (4 Perguntas)

6. Explique Redux e seus princípios básicos.

Resposta: Redux é um contêiner de estado previsível para aplicativos JavaScript.

Loading diagram...
  • Princípios Básicos:
    • Única fonte de verdade (um store)
    • O estado é somente leitura (despache actions para alterar)
    • Alterações feitas com funções puras (reducers)
// Tipos de Action
const ADD_TODO = 'ADD_TODO';
const TOGGLE_TODO = 'TOGGLE_TODO';

// Criadores de Action
const addTodo = (text) => ({
  type: ADD_TODO,
  payload: { id: Date.now(), text, completed: false },
});

const toggleTodo = (id) => ({
  type: TOGGLE_TODO,
  payload: id,
});

// Reducer
const todosReducer = (state = [], action) => {
  switch (action.type) {
    case ADD_TODO:
      return [...state, action.payload];
    case TOGGLE_TODO:
      return state.map(todo =>
        todo.id === action.payload
          ? { ...todo, completed: !todo.completed }
          : todo
      );
    default:
      return state;
  }
};

// Store
import { createStore } from 'redux';
const store = createStore(todosReducer);

// Componente React Native
import { useSelector, useDispatch } from 'react-redux';

function TodoList() {
  const todos = useSelector(state => state.todos);
  const dispatch = useDispatch();
  
  return (
    <View>
      <FlatList
        data={todos}
        renderItem={({ item }) => (
          <TouchableOpacity onPress={() => dispatch(toggleTodo(item.id))}>
            <Text style={{ textDecorationLine: item.completed ? 'line-through' : 'none' }}>
              {item.text}
            </Text>
          </TouchableOpacity>
        )}
      />
      <Button title="Add" onPress={() => dispatch(addTodo('New Task'))} />
    </View>
  );
}

Raridade: Muito Comum Dificuldade: Difícil


7. O que é Redux Toolkit e como ele simplifica o Redux?

Resposta: Redux Toolkit é a maneira oficial recomendada de escrever lógica Redux.

  • Benefícios:
    • Menos boilerplate
    • Immer integrado para atualizações imutáveis
    • Inclui Redux Thunk
    • Melhor suporte para TypeScript
import { createSlice, configureStore } from '@reduxjs/toolkit';

// Slice (combina actions e reducer)
const todosSlice = createSlice({
  name: 'todos',
  initialState: [],
  reducers: {
    addTodo: (state, action) => {
      // Immer permite código "mutante"
      state.push({
        id: Date.now(),
        text: action.payload,
        completed: false,
      });
    },
    toggleTodo: (state, action) => {
      const todo = state.find(t => t.id === action.payload);
      if (todo) {
        todo.completed = !todo.completed;
      }
    },
  },
});

export const { addTodo, toggleTodo } = todosSlice.actions;

// Store
const store = configureStore({
  reducer: {
    todos: todosSlice.reducer,
  },
});

// Async thunk
import { createAsyncThunk } from '@reduxjs/toolkit';

export const fetchTodos = createAsyncThunk(
  'todos/fetchTodos',
  async () => {
    const response = await fetch('https://api.example.com/todos');
    return response.json();
  }
);

const todosSlice = createSlice({
  name: 'todos',
  initialState: { items: [], loading: false, error: null },
  reducers: {},
  extraReducers: (builder) => {
    builder
      .addCase(fetchTodos.pending, (state) => {
        state.loading = true;
      })
      .addCase(fetchTodos.fulfilled, (state, action) => {
        state.loading = false;
        state.items = action.payload;
      })
      .addCase(fetchTodos.rejected, (state, action) => {
        state.loading = false;
        state.error = action.error.message;
      });
  },
});

Raridade: Comum Dificuldade: Média


8. Quais são as alternativas ao Redux para gerenciamento de estado?

Resposta: Existem várias soluções de gerenciamento de estado:

  • Context API + useReducer: Integrado, bom para aplicativos simples
  • MobX: Baseado em observable, menos boilerplate
  • Zustand: Mínimo, baseado em hooks
  • Recoil: Baseado em átomo, pelo Facebook
  • Jotai: Átomos primitivos
// Exemplo Zustand
import create from 'zustand';

const useStore = create((set) => ({
  todos: [],
  addTodo: (text) => set((state) => ({
    todos: [...state.todos, { id: Date.now(), text, completed: false }],
  })),
  toggleTodo: (id) => set((state) => ({
    todos: state.todos.map(todo =>
      todo.id === id ? { ...todo, completed: !todo.completed } : todo
    ),
  })),
}));

// Uso
function TodoList() {
  const { todos, addTodo, toggleTodo } = useStore();
  
  return (
    <View>
      <FlatList
        data={todos}
        renderItem={({ item }) => (
          <TouchableOpacity onPress={() => toggleTodo(item.id)}>
            <Text>{item.text}</Text>
          </TouchableOpacity>
        )}
      />
    </View>
  );
}

Raridade: Comum Dificuldade: Média


9. Como você lida com side effects no Redux?

Resposta: Use middleware para operações assíncronas:

  • Redux Thunk: Funções que retornam funções
  • Redux Saga: Baseado em gerador, mais poderoso
  • Redux Observable: Baseado em RxJS
// Redux Thunk
const fetchUser = (userId) => async (dispatch) => {
  dispatch({ type: 'FETCH_USER_REQUEST' });
  
  try {
    const response = await fetch(`https://api.example.com/users/${userId}`);
    const user = await response.json();
    dispatch({ type: 'FETCH_USER_SUCCESS', payload: user });
  } catch (error) {
    dispatch({ type: 'FETCH_USER_FAILURE', payload: error.message });
  }
};

// Uso
dispatch(fetchUser(123));

// Redux Saga
import { call, put, takeEvery } from 'redux-saga/effects';

function* fetchUserSaga(action) {
  try {
    const user = yield call(fetch, `https://api.example.com/users/${action.payload}`);
    const data = yield call([user, 'json']);
    yield put({ type: 'FETCH_USER_SUCCESS', payload: data });
  } catch (error) {
    yield put({ type: 'FETCH_USER_FAILURE', payload: error.message });
  }
}

function* watchFetchUser() {
  yield takeEvery('FETCH_USER_REQUEST', fetchUserSaga);
}

Raridade: Comum Dificuldade: Difícil


Otimização de Desempenho (5 Perguntas)

10. Como você otimiza o desempenho do FlatList?

Resposta: Várias estratégias melhoram a rolagem do FlatList:

  1. Use keyExtractor: Forneça chaves exclusivas
  2. getItemLayout: Ignore a medição para itens de altura fixa
  3. removeClippedSubviews: Desmonte as visualizações fora da tela (Android)
  4. maxToRenderPerBatch: Controle o tamanho do lote
  5. windowSize: Controle a janela renderizada
  6. initialNumToRender: Itens para renderizar inicialmente
  7. Memorize renderItem: Evite renderizações desnecessárias
import React, { memo, useCallback } from 'react';

const ITEM_HEIGHT = 80;

// Componente de item memorizado
const ListItem = memo(({ item, onPress }) => {
  return (
    <TouchableOpacity onPress={() => onPress(item.id)} style={{ height: ITEM_HEIGHT }}>
      <Text>{item.name}</Text>
    </TouchableOpacity>
  );
});

function OptimizedList({ data }) {
  const handlePress = useCallback((id) => {
    console.log('Pressed:', id);
  }, []);
  
  const renderItem = useCallback(({ item }) => (
    <ListItem item={item} onPress={handlePress} />
  ), [handlePress]);
  
  const keyExtractor = useCallback((item) => item.id.toString(), []);
  
  const getItemLayout = useCallback((data, index) => ({
    length: ITEM_HEIGHT,
    offset: ITEM_HEIGHT * index,
    index,
  }), []);
  
  return (
    <FlatList
      data={data}
      renderItem={renderItem}
      keyExtractor={keyExtractor}
      getItemLayout={getItemLayout}
      removeClippedSubviews={true}
      maxToRenderPerBatch={10}
      updateCellsBatchingPeriod={50}
      initialNumToRender={10}
      windowSize={5}
    />
  );
}

Raridade: Muito Comum Dificuldade: Média


11. O que é a ponte React Native e como ela afeta o desempenho?

Resposta: A ponte é a camada de comunicação entre o JavaScript e o código nativo.

  • Como funciona:
    • JavaScript é executado em uma thread separada
    • Módulos nativos são executados em threads nativas
    • A ponte serializa dados entre eles (JSON)
  • Impacto no Desempenho:
    • A comunicação da ponte é assíncrona
    • Sobrecarga de serialização
    • Pode se tornar um gargalo com comunicação frequente
  • Soluções:
    • Minimize as travessias da ponte
    • Operações em lote
    • Use animações nativas (desvie da ponte)
    • Nova Arquitetura (JSI) remove a ponte
// Ruim - travessias frequentes da ponte
const BadAnimation = () => {
  const [position, setPosition] = useState(0);
  
  useEffect(() => {
    const interval = setInterval(() => {
      setPosition(p => p + 1); // Travessia da ponte a cada frame!
    }, 16);
    return () => clearInterval(interval);
  }, []);
  
  return <View style={{ transform: [{ translateX: position }] }} />;
};

// Bom - animação nativa (sem ponte)
const GoodAnimation = () => {
  const translateX = useRef(new Animated.Value(0)).current;
  
  useEffect(() => {
    Animated.timing(translateX, {
      toValue: 100,
      duration: 1000,
      useNativeDriver: true, // Executa na thread nativa!
    }).start();
  }, []);
  
  return <Animated.View style={{ transform: [{ translateX }] }} />;
};

Raridade: Comum Dificuldade: Difícil


12. Como você evita renderizações desnecessárias?

Resposta: Várias técnicas evitam renderizações desperdiçadas:

  1. React.memo: Memoriza componentes
  2. useMemo/useCallback: Memoriza valores/funções
  3. Props de chave adequadas: Ajuda o React a identificar alterações
  4. Evite objetos/arrays inline: Crie novas referências
  5. Divida os componentes: Componentes menores e focados
// Ruim - cria novo objeto a cada renderização
function BadComponent() {
  return <ChildComponent style={{ margin: 10 }} />; // Novo objeto!
}

// Bom - referência estável
const styles = StyleSheet.create({
  container: { margin: 10 },
});

function GoodComponent() {
  return <ChildComponent style={styles.container} />;
}

// React.memo com comparação personalizada
const ExpensiveComponent = React.memo(
  ({ data, onPress }) => {
    console.log('Rendering ExpensiveComponent');
    return (
      <View>
        <Text>{data.name}</Text>
        <Button onPress={onPress} />
      </View>
    );
  },
  (prevProps, nextProps) => {
    // Comparação personalizada - só renderiza novamente se data.id mudou
    return prevProps.data.id === nextProps.data.id;
  }
);

// Divida os componentes para isolar as renderizações
function ParentComponent() {
  const [count, setCount] = useState(0);
  const [text, setText] = useState('');
  
  return (
    <View>
      {/* Renderiza novamente apenas quando a contagem muda */}
      <CountDisplay count={count} />
      
      {/* Renderiza novamente apenas quando o texto muda */}
      <TextDisplay text={text} />
      
      <Button onPress={() => setCount(c => c + 1)} />
    </View>
  );
}

const CountDisplay = React.memo(({ count }) => <Text>{count}</Text>);
const TextDisplay = React.memo(({ text }) => <Text>{text}</Text>);

Raridade: Muito Comum Dificuldade: Média


13. Como você otimiza imagens no React Native?

Resposta: A otimização de imagem é crucial para o desempenho:

  1. Redimensione as imagens: Use dimensões apropriadas
  2. Armazene imagens em cache: Use bibliotecas como react-native-fast-image
  3. Carregamento lento: Carregue imagens sob demanda
  4. Carregamento progressivo: Mostre o espaço reservado primeiro
  5. Use o formato WebP: Melhor compressão
import FastImage from 'react-native-fast-image';

function OptimizedImage({ uri }) {
  return (
    <FastImage
      source={{
        uri,
        priority: FastImage.priority.normal,
        cache: FastImage.cacheControl.immutable,
      }}
      resizeMode={FastImage.resizeMode.cover}
      style={{ width: 200, height: 200 }}
    />
  );
}

// Carregamento progressivo de imagem
function ProgressiveImage({ thumbnailUri, fullUri }) {
  const [imageLoaded, setImageLoaded] = useState(false);
  
  return (
    <View>
      <Image
        source={{ uri: thumbnailUri }}
        style={styles.image}
        blurRadius={imageLoaded ? 0 : 5}
      />
      <Image
        source={{ uri: fullUri }}
        style={[styles.image, { opacity: imageLoaded ? 1 : 0 }]}
        onLoad={() => setImageLoaded(true)}
      />
    </View>
  );
}

// Pré-busca de imagem
import { Image } from 'react-native';

const prefetchImages = async (urls) => {
  const promises = urls.map(url => Image.prefetch(url));
  await Promise.all(promises);
};

Raridade: Comum Dificuldade: Média


14. Quais ferramentas você usa para profiling de desempenho?

Resposta: Várias ferramentas ajudam a identificar problemas de desempenho:

  • React DevTools Profiler: Tempos de renderização de componentes
  • Flipper: Ferramenta de depuração e profiling
  • Monitor de Desempenho: Monitor de FPS integrado
  • Systrace: Rastreamento de desempenho do Android
  • Instruments: Profiling de desempenho do iOS
// Ative o monitor de desempenho em desenvolvimento
import { LogBox } from 'react-native';

if (__DEV__) {
  // Mostra o monitor de desempenho
  require('react-native').unstable_enableLogBox();
}

// Meça o tempo de renderização do componente
import { Profiler } from 'react';

function onRenderCallback(
  id,
  phase,
  actualDuration,
  baseDuration,
  startTime,
  commitTime
) {
  console.log(`${id} (${phase}) took ${actualDuration}ms`);
}

function App() {
  return (
    <Profiler id="App" onRender={onRenderCallback}>
      <MyComponent />
    </Profiler>
  );
}

// Rastreamento de desempenho personalizado
const measurePerformance = (name, fn) => {
  const start = performance.now();
  const result = fn();
  const end = performance.now();
  console.log(`${name} took ${end - start}ms`);
  return result;
};

Raridade: Comum Dificuldade: Média


Módulos Nativos e Específicos da Plataforma (4 Perguntas)

15. Como você cria um Módulo Nativo no React Native?

Resposta: Módulos nativos permitem que você use código específico da plataforma.

// iOS (Objective-C) - CalendarManager.m
#import "CalendarManager.h"
#import <React/RCTLog.h>

@implementation CalendarManager

RCT_EXPORT_MODULE();

RCT_EXPORT_METHOD(addEvent:(NSString *)name location:(NSString *)location)
{
  RCTLogInfo(@"Creating event %@ at %@", name, location);
}

@end

// Android (Java) - CalendarModule.java
package com.myapp;

import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;

public class CalendarModule extends ReactContextBaseJavaModule {
  CalendarModule(ReactApplicationContext context) {
    super(context);
  }

  @Override
  public String getName() {
    return "CalendarManager";
  }

  @ReactMethod
  public void addEvent(String name, String location) {
    Log.d("CalendarModule", "Creating event " + name + " at " + location);
  }
}

// Uso em JavaScript
import { NativeModules } from 'react-native';

const { CalendarManager } = NativeModules;

function MyComponent() {
  const createEvent = () => {
    CalendarManager.addEvent('Meeting', 'Office');
  };
  
  return <Button title="Create Event" onPress={createEvent} />;
}

Raridade: Média Dificuldade: Difícil


16. Como você lida com código específico da plataforma?

Resposta: Várias abordagens para código específico da plataforma:

  1. Módulo de plataforma: Verifique a plataforma em tempo de execução
  2. Arquivos específicos da plataforma: .ios.js e .android.js
  3. Platform.select: Selecione valores com base na plataforma
import { Platform } from 'react-native';

// Módulo de plataforma
const styles = StyleSheet.create({
  container: {
    paddingTop: Platform.OS === 'ios' ? 20 : 0,
  },
});

// Platform.select
const styles = StyleSheet.create({
  container: {
    ...Platform.select({
      ios: {
        shadowColor: '#000',
        shadowOffset: { width: 0, height: 2 },
        shadowOpacity: 0.3,
      },
      android: {
        elevation: 4,
      },
    }),
  },
});

// Arquivos específicos da plataforma
// Button.ios.js
export default function Button() {
  return <Text>iOS Button</Text>;
}

// Button.android.js
export default function Button() {
  return <Text>Android Button</Text>;
}

// Uso - seleciona automaticamente o arquivo correto
import Button from './Button';

// Verificação da versão da plataforma
if (Platform.Version >= 21) {
  // Android API 21+
}

Raridade: Muito Comum Dificuldade: Fácil


17. O que é a Nova Arquitetura (Fabric e TurboModules)?

Resposta: A Nova Arquitetura melhora o desempenho do React Native:

  • Fabric: Novo sistema de renderização
    • Layout síncrono
    • Melhor interoperação com visualizações nativas
    • Type safety
  • TurboModules: Novo sistema de módulo nativo
    • Carregamento lento
    • JSI (JavaScript Interface) - comunicação C++ direta
    • Sem serialização de ponte

Benefícios:

  • Inicialização mais rápida
  • Menor uso de memória
  • Chamadas nativas síncronas
  • Melhor type safety

Raridade: Média Dificuldade: Difícil


18. Como você lida com deep linking no React Native?

Resposta: Deep linking permite abrir telas específicas a partir de URLs.

import { Linking } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';

// Configure deep linking
const linking = {
  prefixes: ['myapp://', 'https://myapp.com'],
  config: {
    screens: {
      Home: 'home',
      Profile: 'profile/:id',
      Settings: 'settings',
    },
  },
};

function App() {
  return (
    <NavigationContainer linking={linking}>
      <Stack.Navigator>
        <Stack.Screen name="Home" component={HomeScreen} />
        <Stack.Screen name="Profile" component={ProfileScreen} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

// Lida com links recebidos
useEffect(() => {
  const handleUrl = ({ url }) => {
    console.log('Opened with URL:', url);
    // myapp://profile/123
  };
  
  // Aplicativo aberto a partir do link
  Linking.getInitialURL().then(url => {
    if (url) handleUrl({ url });
  });
  
  // Aplicativo já aberto, novo link
  const subscription = Linking.addEventListener('url', handleUrl);
  
  return () => subscription.remove();
}, []);

// Abra a URL programaticamente
const openURL = async (url) => {
  const supported = await Linking.canOpenURL(url);
  if (supported) {
    await Linking.openURL(url);
  }
};

Raridade: Comum Dificuldade: Média


Testes (3 Perguntas)

19. Como você testa componentes React Native?

Resposta: Use bibliotecas de teste como Jest e React Native Testing Library.

import { render, fireEvent, waitFor } from '@testing-library/react-native';
import Counter from './Counter';

describe('Counter', () => {
  it('renders initial count', () => {
    const { getByText } = render(<Counter />);
    expect(getByText('Count: 0')).toBeTruthy();
  });
  
  it('increments count when button pressed', () => {
    const { getByText, getByTestId } = render(<Counter />);
    const button = getByTestId('increment-button');
    
    fireEvent.press(button);
    
    expect(getByText('Count: 1')).toBeTruthy();
  });
  
  it('fetches user data', async () => {
    const mockFetch = jest.fn(() =>
      Promise.resolve({
        json: ()
Newsletter subscription

Dicas de carreira semanais que realmente funcionam

Receba as últimas ideias diretamente na sua caixa de entrada

Crie um Currículo que Te Contrate 60% Mais Rápido

Em minutos, crie um currículo personalizado e compatível com ATS comprovado para conseguir 6 vezes mais entrevistas.

Crie um currículo melhor

Compartilhar esta publicação

Seja Contratado 50% Mais Rápido

Candidatos que usam currículos profissionais aprimorados por IA conseguem vagas em uma média de 5 semanas comparado às 10 padrão. Pare de esperar e comece a fazer entrevistas.