React Native でアイコンタップでクリップボードにコピーする

コピーアイコンをタップしたタイミングでクリップボードにコピーする方法を紹介します。

公式ページ通りのシンプルな作業です。

ライブラリをインストール

shell
npm install --save @react-native-clipboard/clipboard

Clipboard を import する

Sample.tsx
import Clipboard from '@react-native-clipboard/clipboard';

コピーアイコンをタップしたタイミングでクリップボードにコピー

Sample.tsx
<MaterialIcons
          name="content-copy"
          size={24}
          color="black"
          style={styles.copyIcon}
          onPress={() => {
            Clipboard.setString(body);
          }}
        />

@react-native-clipboard/clipboard は Expo で使うとエラーが出る

shell
 ERROR  Invariant Violation: Your JavaScript code tried to access a native module that doesn't exist. 

If you're trying to use a module that is not supported in Expo Go, you need to create a development build of your app. See https://docs.expo.dev/development/introduction/ for more info., js engine: hermes
 ERROR  Invariant Violation: "main" has not been registered. This can happen if:
* Metro (the local dev server) is run from the wrong folder. Check if Metro is running, stop it and restart it in the current project.
* A module failed to load due to an error and `AppRegistry.registerComponent` wasn't called., js engine: hermes
 ERROR  Invariant Violation: Your JavaScript code tried to access a native module that doesn't exist. 

@react-native-clipboard/clipboard をアンインストールする

shell
 npm uninstall --save @react-native-clipboard/clipboard

expo-clipboard をインストール

shell
npx expo install expo-clipboard

アイコンタップでコピー(Expo)

Sample.tsx
import * as Clipboard from 'expo-clipboard';
Sample.tsx
        <MaterialIcons
          name="content-copy"
          size={24}
          color="black"
          style={styles.copyIcon}
          onPress={() => {
            Clipboard.setStringAsync(body).then(() => {
              console.log('Copied to clipboard');
            });
          }}
        />

以下のように、コピーのタイミングで Toast を出したり、Haptics Feedback で端末を震わせてあげるとユーザーもわかりやすいかもしれません。

Sample.tsx
     <MaterialIcons
          name="content-copy"
          size={24}
          color="black"
          style={styles.copyIcon}
          onPress={() => {
            Clipboard.setStringAsync(body).then(() => {
              Haptics.notificationAsync(Haptics.NotificationFeedbackType.Success);
              Toast.show({
                type: 'success',
                text1: 'Copied to clipboard',
                visibilityTime: 1000,
              });
            });
          }}
        />