'분류 전체보기'에 해당되는 글 43건

  1. 2023.03.16 ReactNative의 Animated
  2. 2023.03.15 ReactNative에서 리덕스 미들웨어 활용
  3. 2023.03.14 리덕스 툴킷과 ReactNative
  4. 2023.03.13 Redux와 ReactNative
  5. 2023.03.12 ReactNative의 복합 컴포넌트 패턴

Animated 컴포넌트는 애니메이션을 생성하고 관리하기 위한 강력한 API를 제공하는 기본 제공 ReactNative 컴포넌트입니다. Animated를 사용하면 개발자는 시간 제한 애니메이션, 연쇄 애니메이션, 물리 기반 애니메이션을 포함한 복잡한 애니메이션과 상호작용을 쉽게 만들 수 있습니다. 애니메이션 컴포넌트는 애니메이션 값을 사용자 인터페이스 컴포넌트의 애니메이션 프로퍼티에 매핑하는 방식으로 작동합니다.

다음은 ReactNative에서 Animated 컴포넌트를 사용하는 두 가지 예시 코드입니다.

버튼 누르기 애니메이션 적용

import React, { useRef } from 'react';
import { View, TouchableOpacity, Text, Animated } from 'react-native';

const ButtonAnimation = () => {
  const scaleAnim = useRef(new Animated.Value(1)).current;

  const onPressIn = () => {
    Animated.spring(scaleAnim, {
      toValue: 0.8,
      useNativeDriver: true,
    }).start();
  };

  const onPressOut = () => {
    Animated.spring(scaleAnim, {
      toValue: 1,
      useNativeDriver: true,
    }).start();
  };

  return (
    <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
      <TouchableOpacity onPressIn={onPressIn} onPressOut={onPressOut}>
        <Animated.View style={{ transform: [{ scale: scaleAnim }] }}>
          <Text style={{ fontSize: 20, fontWeight: 'bold' }}>Press me</Text>
        </Animated.View>
      </TouchableOpacity>
    </View>
  );
};

export default ButtonAnimation;

 

뷰 페이드 인

import React, { useState, useEffect } from 'react';
import { View, Animated } from 'react-native';

const App = () => {
  const [fadeAnim] = useState(new Animated.Value(0));

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

  return (
    <Animated.View style={{ opacity: fadeAnim }}>
      <View>
        <Text>Hello World!</Text>
      </View>
    </Animated.View>
  );
};

export default App;

이 예제에서는 fadeAnim이라는 새로운 애니메이션 값 객체를 생성하고 useState 훅을 사용하여 0으로 초기화합니다. 그런 다음, 컴포넌트가 마운트될 때 애니메이션을 시작하기 위해 useEffect 훅을 사용합니다. Animated.timing 메서드를 사용하여 Animated.View 컴포넌트에서 1000밀리초(1초)의 기간 동안 애니메이션이 페이드됩니다. 사용NativeDriver 옵션을 true로 설정하면 성능이 향상됩니다.

 

본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성되었습니다.
http://bit.ly/3Y34pE0

Posted by cipleee

Redux 미들웨어는 비동기 액션과 부작용을 처리하기 위해 React Native 애플리케이션에서 사용되는 강력한 도구입니다. 다음은 React Native에서 자주 사용되는 몇 가지 Redux 미들웨어입니다

Redux Thunk 미들웨어

Redux Thunk 미들웨어를 사용하면 액션 객체 대신 함수를 반환하는 액션 크리에이터를 작성할 수 있습니다. 반환된 함수는 인자로 dispatch를 받을 수 있으며 비동기적으로 액션을 디스패치할 수 있습니다.

import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from './reducers';

const store = createStore(
  rootReducer,
  applyMiddleware(thunk)
);
// Example action creator using Redux Thunk middleware
export const fetchUser = (userId) => {
  return (dispatch) => {
    dispatch({ type: 'FETCH_USER_REQUEST' });
    fetch(`https://api.example.com/users/${userId}`)
      .then(response => response.json())
      .then(data => dispatch({ type: 'FETCH_USER_SUCCESS', payload: data }))
      .catch(error => dispatch({ type: 'FETCH_USER_FAILURE', payload: error }));
  };
};

Redux 사가 미들웨어

Redux Saga 미들웨어는 비동기 API 호출과 같은 복잡한 부작용을 쉽게 처리할 수 있는 강력한 라이브러리입니다. 제너레이터를 사용하여 비동기 작업의 흐름을 관리하고 동시성 및 취소와 같은 복잡한 시나리오를 처리할 수 있는 강력한 도구를 제공합니다.

import { createStore, applyMiddleware } from 'redux';
import createSagaMiddleware from 'redux-saga';
import rootReducer from './reducers';
import { userSaga } from './sagas';

const sagaMiddleware = createSagaMiddleware();

const store = createStore(
  rootReducer,
  applyMiddleware(sagaMiddleware)
);

sagaMiddleware.run(userSaga);
// Example Saga to handle user data fetching
import { call, put, takeLatest } from 'redux-saga/effects';
import { fetchUserSuccess, fetchUserFailure } from './actions';
import { FETCH_USER_REQUEST } from './actionTypes';

function* fetchUser(action) {
  try {
    const response = yield call(fetch, `https://api.example.com/users/${action.payload}`);
    const data = yield response.json();
    yield put(fetchUserSuccess(data));
  } catch (error) {
    yield put(fetchUserFailure(error));
  }
}

export function* userSaga() {
  yield takeLatest(FETCH_USER_REQUEST, fetchUser);
}

Redux 퍼시스트 미들웨어

Redux 퍼시스트 미들웨어를 사용하면 Redux 저장소를 로컬 스토리지 또는 다른 스토리지 메커니즘에 퍼시스트할 수 있습니다. 세션 간에 또는 사용자가 페이지를 새로 고칠 때 애플리케이션의 상태를 유지하려는 경우에 유용합니다.

import { createStore, applyMiddleware } from 'redux';
import { persistStore, persistReducer } from 'redux-persist';
import AsyncStorage from '@react-native-async-storage/async-storage';
import rootReducer from './reducers';

const persistConfig = {
  key: 'root',
  storage: AsyncStorage,
};

const persistedReducer = persistReducer(persistConfig, rootReducer);

const store = createStore(
  persistedReducer,
  applyMiddleware()
);

const persistor = persistStore(store);
// Example usage of persisted store in a React component
import { PersistGate } from 'redux-persist/integration/react';
import { Provider } from 'react-redux';
import { store, persistor } from './store';
import App from './App';

export default function Root() {
  return (
    <Provider store={store}>
      <PersistGate loading={null} persistor={persistor}>
        <App />
      </PersistGate>
    </Provider>
  );
}

이들은 React Native 애플리케이션에서 가장 자주 사용되는 Redux 미들웨어 중 일부입니다. 하지만 애플리케이션의 복잡한 시나리오를 처리하는 데 도움이 되는 더 많은 미들웨어를 사용할 수 있습니다.

 

본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성되었습니다.
http://bit.ly/3Y34pE0

Posted by cipleee

리덕스 툴킷은 Redux 로직을 작성하는 과정을 간소화하는 패키지입니다. 기본적으로 Redux 코드를 더 빠르고 쉽게 작성할 수 있는 유틸리티와 규칙의 집합입니다. 개발자들이 Redux로 작업하면서 겪었던 몇 가지 일반적인 문제점을 해결하기 위해 Redux 팀에서 만들었습니다.

리덕스 툴킷의 주요 동기 중 하나는 상용구 코드를 줄이는 것이었습니다. 개발자들은 Redux를 사용할 때 액션과 리듀서 설정과 같은 일반적인 작업을 처리하기 위해 반복적인 코드를 많이 작성해야 하는 경우가 많다는 것을 알게 되었습니다. 이로 인해 코드가 더 장황해지고 유지 관리가 더 어려워졌습니다.

또한 리덕스 툴킷은 최신 웹 애플리케이션의 일반적인 사용 사례인 비동기 코드를 더 쉽게 작업할 수 있도록 하는 것을 목표로 했습니다. 리덕스 툴킷을 사용하면 개발자는 createAsyncThunk 함수를 사용하여 비동기 요청을 보다 간소화된 방식으로 처리할 수 있습니다.

이러한 기능 외에도 리덕스 툴킷은 Redux 코드를 보다 체계적으로 구조화할 수 있는 방법도 제공합니다. 개발자는 Redux Toolkit에서 제시하는 규칙을 따라 코드를 보다 일관성 있고 이해하기 쉽게 만들 수 있습니다.

다음은 React Native 앱에서 리덕스 툴킷을 사용하는 방법의 예시입니다.

import React from 'react';
import { View, Text, Button, SafeAreaView } from 'react-native';
import { Provider, useSelector, useDispatch } from 'react-redux';
import { configureStore, createSlice } from '@reduxjs/toolkit';

// Define a slice of the Redux store
const counterSlice = createSlice({
  name: 'counter',
  initialState: { value: 0 },
  reducers: {
    increment: (state) => {
      state.value += 1;
    },
    decrement: (state) => {
      state.value -= 1;
    },
  },
});

// Create the Redux store using the configureStore function
const store = configureStore({
  reducer: {
    counter: counterSlice.reducer,
  },
});

const App = () => {
  return (
    // Wrap the app in a Provider component to make the Redux store available to all components
    <Provider store={store}>
      <SafeAreaView>
        <Counter />
      </SafeAreaView>
    </Provider>
  );
};

const Counter = () => {
  const counter = useSelector((state) => state.counter.value);
  const dispatch = useDispatch();

  return (
    <View>
      <Text>{counter}</Text>
      <Button title="Increment" onPress={() => dispatch(counterSlice.actions.increment())} />
      <Button title="Decrement" onPress={() => dispatch(counterSlice.actions.decrement())} />
    </View>
  );
};

export default App;

이 예제에서는 createSlice 함수를 사용하여 Redux 저장소의 슬라이스를 정의합니다. 그런 다음 configureStore 함수를 사용하여 Redux 스토어를 생성하고 슬라이스를 감속기로 전달합니다. 마지막으로, 모든 컴포넌트에서 스토어를 사용할 수 있도록 앱을 프로바이더 컴포넌트로 래핑합니다.

카운터 컴포넌트 내부에서는 React Redux에서 제공하는 useSelector와 useDispatch 훅을 사용해 카운터 상태에 접근하고 스토어에 액션을 디스패치합니다. 슬라이스에서 액션 생성자를 디스패치 함수에 전달하여 상태를 업데이트합니다.

 

본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성되었습니다.
http://bit.ly/3Y34pE0

Posted by cipleee

Redux는 자바스크립트 애플리케이션을 위한 예측 가능한 상태 컨테이너를 제공하는 상태 관리 라이브러리입니다. 애플리케이션의 상태를 중앙에서 관리할 수 있으므로 코드를 더 쉽게 이해하고 디버깅할 수 있습니다. Redux의 핵심 개념은 애플리케이션의 전체 상태를 보관하는 JavaScript 객체인 저장소입니다. 상태의 변경 사항을 설명하는 일반 JavaScript 객체인 액션을 사용하여 스토어를 업데이트할 수 있습니다. 리듀서는 현재 상태와 액션을 받아 새로운 상태를 반환하는 순수 함수입니다.

다음은 React Native 애플리케이션에서 Redux를 사용하는 방법을 보여주는 예시 코드입니다

먼저 필요한 패키지를 설치해야 합니다.

npm install redux react-redux

다음으로 스토어와 reducer를 생성합니다

import { createStore } from 'redux';

const initialState = {
  counter: 0
};

const reducer = (state = initialState, action) => {
  switch (action.type) {
    case 'INCREMENT':
      return {
        ...state,
        counter: state.counter + 1
      };
    case 'DECREMENT':
      return {
        ...state,
        counter: state.counter - 1
      };
    default:
      return state;
  }
};

const store = createStore(reducer);

이 예제에서 스토어의 초기 상태에는 0으로 설정된 카운터 변수가 포함되어 있습니다. reducer는 현재 상태와 작업을 입력으로 받아 작업 유형에 따라 새 상태를 반환합니다.

 

컴포넌트에서 store를 사용하려면 react-redux의 connect 함수를 사용하여 컴포넌트를 store에 연결해야 합니다

import React from 'react';
import { View, Text, Button } from 'react-native';
import { connect } from 'react-redux';

const Counter = ({ counter, increment, decrement }) => {
  return (
    <View>
      <Text>{counter}</Text>
      <Button title="Increment" onPress={increment} />
      <Button title="Decrement" onPress={decrement} />
    </View>
  );
};

const mapStateToProps = state => ({
  counter: state.counter
});

const mapDispatchToProps = dispatch => ({
  increment: () => dispatch({ type: 'INCREMENT' }),
  decrement: () => dispatch({ type: 'DECREMENT' })
});

export default connect(mapStateToProps, mapDispatchToProps)(Counter);

이 예제에서 카운터 컴포넌트는 mapStateToProps 함수를 통해 스토어에서 카운터 prop을 받습니다. 증가 및 감소 함수는 mapDispatchToProps 함수를 통해 버튼 컴포넌트의 onPress 이벤트에 매핑됩니다. 버튼 컴포넌트를 누르면 해당 액션이 스토어로 디스패치되어 상태가 업데이트되고 컴포넌트가 다시 렌더링됩니다.

 

본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성되었습니다.
http://bit.ly/3Y34pE0

Posted by cipleee

복합 컴포넌트 패턴은 여러 개의 작은 컴포넌트로 구성된 컴포넌트를 만들 수 있는 디자인 패턴으로, 여러 가지 방식으로 결합하여 다양한 기능을 구현할 수 있습니다. 이 패턴의 핵심 아이디어는 관련 컴포넌트를 함께 그룹화하고 사용자가 특정 사용 사례에 적합한 방식으로 사용할 수 있도록 하는 방법을 제공하는 것입니다.

ReactNative에서 복합 컴포넌트 패턴은 여러 자식 컴포넌트를 렌더링하는 부모 컴포넌트를 사용하여 구현할 수 있습니다. 각 자식 컴포넌트는 자체 프로퍼티로 커스터마이징할 수 있지만, 부모 컴포넌트가 전체적인 동작과 모양을 제어합니다.

예를 들어 헤더와 본문이 있는 카드를 렌더링하는 컴포넌트를 만들고 싶다고 가정해 봅시다. 두 개의 자식 컴포넌트를 받아들이는 Card 컴포넌트를 만들 수 있습니다: 헤더와 본문. 카드 컴포넌트는 헤더와 바디 컴포넌트를 렌더링하고 필요한 소품을 제공합니다.

다음은 구현 예시입니다.

import React from 'react';
import { View, StyleSheet, Text } from 'react-native';

const styles = StyleSheet.create({
  card: {
    backgroundColor: '#fff',
    borderRadius: 10,
    shadowColor: '#000',
    shadowOpacity: 0.1,
    shadowRadius: 10,
    shadowOffset: { width: 0, height: 0 },
    elevation: 1,
  },
});

const Card = ({ children }) => (
  <View style={styles.card}>
    {children}
  </View>
);

const Header = ({ title }) => (
  <View>
    <Text>{title}</Text>
  </View>
);

const Body = ({ children }) => (
  <View>
    {children}
  </View>
);

Card.Header = Header;
Card.Body = Body;

export default Card;

이 구현에서는 Card 컴포넌트와 그 하위 컴포넌트인 Header 및 Body를 정의합니다. 자식 프로퍼티를 사용해 Card 컴포넌트 내부의 Header와 Body 컴포넌트를 렌더링합니다.

사용자가 헤더 및 본문 컴포넌트를 사용자 정의할 수 있도록 각 컴포넌트에 대한 프롭을 정의하고(이 예제에서는 헤더 컴포넌트가 제목 프롭을 허용함) 컴포넌트를 사용할 때 이를 전달합니다.

마지막으로 Card 컴포넌트를 내보내고 Header 및 Body 컴포넌트를 프로퍼티로 첨부합니다. 이렇게 하면 사용자가 Card 컴포넌트를 가져와서 다음과 같이 사용할 수 있습니다.

 

import React from 'react';
import { Text } from 'react-native';
import Card from './Card';

const MyComponent = () => (
  <Card>
    <Card.Header title="My Card Title" />
    <Card.Body>
      <Text>My Card Body</Text>
    </Card.Body>
  </Card>
);

export default MyComponent;

복합 컴포넌트 패턴을 사용하면 특정 사용 사례에 따라 다양한 방식으로 커스터마이징할 수 있는 유연하고 재사용 가능한 컴포넌트를 만들 수 있습니다.

본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성되었습니다.
http://bit.ly/3Y34pE0

Posted by cipleee