React Native

react-native-keyboard-controller 사용하기

은퇴하는 그날까지 2024. 5. 12. 19:29

모바일 환경에서는 키보드 입력시 가상 키패드가 화면에 나타나서 컨텐츠를 가리게 되는데 이것을 막기 위해서 React Native 에서는 KeyboardAvoidingView 를 기본적으로 제공해준다.

 

그런데 막상 사용해보니 여러가지 문제가 발생했고 옵션을 변경하며 나름 바꿔보려 했으나 코드가 지저분해지고 잘 해결되지 않았다..🥲

(발생한 문제)

  • 키보드가 떠있는상태로 다른 화면으로 이동하면 화면이 올라가 있다.
  • flex 인 요소는 요소 사이에 높이가 정해지지 않아서 요소와 요소가 붙어버린다.
    • (스크롤 뷰를 직접 넣어서 padding 이 아닌 다른 옵션을 넣는등에 작업을 하면 해결할 수 있을거 같긴한데 지전분해지는 느낌을 받았다..)

라이브러리를 찾아보던 중 타입스크립트 지원도 잘 되고, 옵션도 많은 react-native-keyboard-controller 를 사용하기로 결정했고 적용하는 방법을 적어본다.

설치

먼저 react-native-keyboard-controller 라이브러는 react-native-reanimate 에 의존하고 있기 때문에 먼저 이것을 설치해주어야 한다.

npm i react-native-reanimate

라이브러리 설치가 끝나면 babel.config.js 를 수정해준다.

module.exports = {
  presets: ['module:@react-native/babel-preset'],
  plugins: [
    'babel-plugin-styled-components', 
    'module:react-native-dotenv',
    'react-native-reanimated/plugin', /// ⭐️ 이부분 추가 !! 
  ],
};

다른 플러그인은 다른 라이브러리 때문에 넣은것이라 무시해도 되고, 중요한 것은 react-native-reanimated/plugin 를 plugins 배열에 맨 마지막에 넣는것이다. (순서 중요❗️)

다음으로 react-native-keyboard-controller 를 설치해준다.

npm i react-native-keyboard-controller

사용

사용을 위해서 Provider 를 App.tsx 에 화면 요소를 감싸게 추가해준다.

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 *
 * @format
 */

import React from 'react';
// .... 다른 라이브러리 
import {KeyboardProvider} from 'react-native-keyboard-controller';

function App(): React.JSX.Element {
  const isDarkMode = useColorScheme() === 'dark';

  return (
    <QueryClientProvider client={queryClient}>
      <ThemeProvider theme={isDarkMode ? dark : light}>
        <RecoilRoot>
          <KeyboardProvider> {/* ⭐️ 이부분 추가 */}
            <SafeAreaProvider>
              <NavigationContainer>
                <Pressable onPress={Keyboard.dismiss} style={styles.rootScreen}>
                  <RootRouter />
                  <Dialog />
                  <CommonIndicator />
                  <Alert />
                </Pressable>
                <AuthEffect />
              </NavigationContainer>
            </SafeAreaProvider>
          </KeyboardProvider>
        </RecoilRoot>
      </ThemeProvider>
    </QueryClientProvider>
  );
}

공통 컴포넌트를 만들어서 적용이 필요한 화면에서 공통으로 사용할 수 있도록 한다. (이 부분은 필요에 따라서 적용하거나 다른 방식으로 해도무관)
KeyboardAvoid.tsx 를 추가한다.

import React from 'react';
import {KeyboardAwareScrollView} from 'react-native-keyboard-controller';

type KeyboardAvoidProps = {
  children: React.ReactNode;
};

export default function KeyboardAvoid({children}: KeyboardAvoidProps) {
  return (
    <KeyboardAwareScrollView style={{flex: 1}} bottomOffset={40}>
      {children}
    </KeyboardAwareScrollView>
  );
}

적용이 필요한 화면을 깜싸서 사용한다. (SignUpScreen.tsx)

import React from 'react';
import Layout from '../components/common/Layout';
import Header from '../components/common/Header';
import SignUpBody from '../components/SignUpScreen/SignUpBody';
import KeyboardAvoid from '../components/common/KeyboardAvoid';

export default function SignUpScreen() {
  return (
    <Layout>
      <Layout.Header>
        <Header title="회원가입" backBtn />
      </Layout.Header>
      <Layout.BodyWithHeader>
        <KeyboardAvoid> {/* ⭐️ 이부분 추가 */}
          <SignUpBody />
        </KeyboardAvoid>
      </Layout.BodyWithHeader>
    </Layout>
  );
}

이제 키보드가 올라올때 화면이 같이 올라가고 스크롤도 가능하게 된다.😎