共通コンポーネント
ここでは冗長な箇所をリファクタリングしていきます。
KeyboardAvoidingViewの共通コンポーネント化
現在、KeyboardAvoidingViewはログイン画面とToDo登録画面の二か所で使用しており、いずれもbehaviorに同様のキーボード動作を指定します。
ここに追加や変更が生じた場合、変更が複数箇所にまたがり修正漏れなどのリスクが生じます。
そこで、この箇所を共通コンポーネント化することで上記問題に対処します。
今回作成するコンポーネントは汎用性があるため、ToDoアプリプロジェクトの準備に示すとおり、components/basicsに作成します。
次のファイルを追加してください。
src/components/basics/view/KeyboardView.tsxsrc/components/basics/view/index.tssrc/components/basics/index.ts
src/components/basics/view/KeyboardView.tsx
import React, {ComponentProps} from 'react';
import {KeyboardAvoidingView, Platform, StyleSheet} from 'react-native';
type KeyboardViewProps = ComponentProps<typeof KeyboardAvoidingView>;
const defaultKeyboardAvoidingViewBehavior = Platform.select({
  ios: 'padding',
  android: undefined,
} as const);
export const KeyboardView: React.FC<KeyboardViewProps> = ({
  children,
  behavior = defaultKeyboardAvoidingViewBehavior,
  style,
  ...props
}) => {
  return (
    <KeyboardAvoidingView behavior={behavior} style={StyleSheet.flatten([styles.container, style])} {...props}>
      {children}
    </KeyboardAvoidingView>
  );
};
const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
});
src/components/basics/view/index.ts
export * from './KeyboardView';
src/components/basics/index.ts
export * from './view';
追加が出来たらKeyboardAvoidingViewを使用している箇所を修正していきます。
次のファイルを修正してください。
src/screens/auth/Login.tsxsrc/screens/todo/TodoForm.tsx
src/screens/auth/Login.tsx
+ import {KeyboardView} from 'components/basics';
  import {useUserContext} from 'contexts/UserContext';
  import {useFormik} from 'formik';
  import React, {useCallback} from 'react';
- import {KeyboardAvoidingView, Platform, StyleSheet, View} from 'react-native';
+ import {StyleSheet, View} from 'react-native';
  import {Button, Input} from 'react-native-elements';
  import * as Yup from 'yup';
  
  export const Login: React.FC = () => {
  /* ~省略~ */
  
    return (
-     <KeyboardAvoidingView
-       behavior={Platform.select({
-         ios: 'padding',
-         android: undefined,
-       } as const)}
-       style={styles.container}>
+     <KeyboardView>
  /* ~省略~ */
-     </KeyboardAvoidingView>
+     </KeyboardView>
    );
  };
  
  const styles = StyleSheet.create({
-   container: {
-     flex: 1,
-   },
  /* ~省略~ */
src/screens/todo/TodoForm.tsx
  import {useNavigation} from '@react-navigation/native';
+ import {KeyboardView} from 'components/basics';
  import {useFormik} from 'formik';
  import React, {useCallback, useEffect} from 'react';
- import {Alert, KeyboardAvoidingView, Platform, StyleSheet, View} from 'react-native';
+ import {Alert, StyleSheet, View} from 'react-native';
  import {Button, Input, Text} from 'react-native-elements';
  import {TodoService} from 'services';
  import * as Yup from 'yup';
  
  export const TodoForm: React.FC = () => {
  /* ~省略~ */
  
    return (
-     <KeyboardAvoidingView
-       behavior={Platform.select({
-         ios: 'padding',
-         android: undefined,
-       } as const)}
-       style={styles.container}>
+     <KeyboardView>
  /* ~省略~ */
-     </KeyboardAvoidingView>
+     </KeyboardView>
    );
  };
  
  const styles = StyleSheet.create({
-   container: {
-     flex: 1,
-   },
  /* ~省略~ */
修正できたら実行してください。 以前と変わらず動作できたら成功です。