Front/React

React Native ์‹ฌํ™”

oodada 2024. 11. 2. 22:52

React Native ์‹ฌํ™” ๐Ÿ“š

1. ๋„ค๋น„๊ฒŒ์ด์…˜

Stack Navigation

// ๊ธฐ๋ณธ ์Šคํƒ ๋„ค๋น„๊ฒŒ์ด์…˜ ์„ค์ •
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';

const Stack = createStackNavigator();

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

Tab Navigation

import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';

const Tab = createBottomTabNavigator();

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

2. API ์—ฐ๋™

Fetch ์‚ฌ์šฉํ•˜๊ธฐ

function DataFetching() {
  const [data, setData] = useState([]);

  useEffect(() => {
    fetch('https://api.example.com/data')
      .then(response => response.json())
      .then(json => setData(json))
      .catch(error => console.error(error));
  }, []);

  return (
    <FlatList
      data={data}
      renderItem={({ item }) => <Text>{item.title}</Text>}
    />
  );
}

Axios ์‚ฌ์šฉํ•˜๊ธฐ

import axios from 'axios';

function DataFetching() {
  const [data, setData] = useState([]);

  useEffect(() => {
    async function fetchData() {
      try {
        const response = await axios.get('https://api.example.com/data');
        setData(response.data);
      } catch (error) {
        console.error(error);
      }
    }
    fetchData();
  }, []);
}

3. ๋กœ์ปฌ ๋ฐ์ดํ„ฐ ์ €์žฅ

AsyncStorage

import AsyncStorage from '@react-native-async-storage/async-storage';

// ๋ฐ์ดํ„ฐ ์ €์žฅ
const storeData = async value => {
  try {
    await AsyncStorage.setItem('my-key', JSON.stringify(value));
  } catch (e) {
    console.error(e);
  }
};

// ๋ฐ์ดํ„ฐ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ
const getData = async () => {
  try {
    const value = await AsyncStorage.getItem('my-key');
    return value != null ? JSON.parse(value) : null;
  } catch (e) {
    console.error(e);
  }
};

4. ํ‘ธ์‹œ ์•Œ๋ฆผ

Expo Notifications

import * as Notifications from 'expo-notifications';

// ์•Œ๋ฆผ ๊ถŒํ•œ ์š”์ฒญ
async function registerForPushNotifications() {
  const { status } = await Notifications.requestPermissionsAsync();
  if (status !== 'granted') {
    alert('์•Œ๋ฆผ ๊ถŒํ•œ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค!');
    return;
  }

  const token = (await Notifications.getExpoPushTokenAsync()).data;
  return token;
}

// ๋กœ์ปฌ ์•Œ๋ฆผ ๋ณด๋‚ด๊ธฐ
async function scheduleNotification() {
  await Notifications.scheduleNotificationAsync({
    content: {
      title: '์•Œ๋ฆผ ์ œ๋ชฉ',
      body: '์•Œ๋ฆผ ๋‚ด์šฉ์ž…๋‹ˆ๋‹ค.',
    },
    trigger: { seconds: 2 },
  });
}

5. ์„ฑ๋Šฅ ์ตœ์ ํ™”

React.memo ์‚ฌ์šฉ

const MyComponent = React.memo(function MyComponent(props) {
  return (
    <View>
      <Text>{props.text}</Text>
    </View>
  );
});

useCallback ํ™œ์šฉ

function ParentComponent() {
  const [count, setCount] = useState(0);

  const handlePress = useCallback(() => {
    setCount(c => c + 1);
  }, []);

  return <ChildComponent onPress={handlePress} />;
}

6. ์•ฑ ๋ฐฐํฌ

Android ๋ฐฐํฌ ์ค€๋น„

  1. ์•ฑ ์„œ๋ช… ํ‚ค ์ƒ์„ฑ
  2. build.gradle ์„ค์ •
  3. ๋ฆด๋ฆฌ์ฆˆ ๋นŒ๋“œ ์ƒ์„ฑ

iOS ๋ฐฐํฌ ์ค€๋น„

  1. Apple Developer ๊ณ„์ • ์„ค์ •
  2. ์ธ์ฆ์„œ ๋ฐ ํ”„๋กœ๋น„์ €๋‹ ํ”„๋กœํŒŒ์ผ ์„ค์ •
  3. Xcode์—์„œ ๋นŒ๋“œ ๋ฐ ์•„์นด์ด๋ธŒ

7. ํ…Œ์ŠคํŠธ

Jest ์‚ฌ์šฉํ•˜๊ธฐ

import renderer from 'react-test-renderer';

test('์ปดํฌ๋„ŒํŠธ ๋ Œ๋”๋ง ํ…Œ์ŠคํŠธ', () => {
  const tree = renderer.create(<MyComponent />).toJSON();
  expect(tree).toMatchSnapshot();
});

8. ์• ๋‹ˆ๋ฉ”์ด์…˜

Animated ์‚ฌ์šฉ

import { Animated } from 'react-native';

function FadeInView() {
  const fadeAnim = useRef(new Animated.Value(0)).current;

  useEffect(() => {
    Animated.timing(fadeAnim, {
      toValue: 1,
      duration: 1000,
      useNativeDriver: true,
    }).start();
  }, []);

  return (
    <Animated.View style={{ opacity: fadeAnim }}>
      <Text>ํŽ˜์ด๋“œ์ธ ํšจ๊ณผ</Text>
    </Animated.View>
  );
}

9. ์ƒํƒœ ๊ด€๋ฆฌ

Recoil ์‚ฌ์šฉ

import { atom, selector, useRecoilState, useRecoilValue } from 'recoil';

// ์•„ํ†ฐ ์ƒ์„ฑ
const counterState = atom({
  key: 'counterState',
  default: 0,
});

// ์…€๋ ‰ํ„ฐ ์ƒ์„ฑ
const doubledCounterState = selector({
  key: 'doubledCounterState',
  get: ({ get }) => {
    const count = get(counterState);
    return count * 2;
  },
});

function Counter() {
  const [count, setCount] = useRecoilState(counterState);
  const doubledCount = useRecoilValue(doubledCounterState);

  return (
    <View>
      <Text>Count: {count}</Text>
      <Text>Doubled Count: {doubledCount}</Text>
      <Button
        onPress={() => setCount(count + 1)}
        title="Increment"
      />
    </View>
  );
}

function App() {
  return (
    <RecoilRoot>
      <Counter />
    </RecoilRoot>
  );
}
ํ‹ฐ์Šคํ† ๋ฆฌ ์นœ๊ตฌํ•˜๊ธฐ