Ava Juan
Ava Juan

Reputation: 113

React Native Copy the text loaded via API to Clipboard

I'm Feching the Data from API and I want to Copy that text when the Copy Button is pressed.

I'm using @react-native-community/clipboard

And showing the data with {item.content}

I don't know why the text got from api is not copying into clipboard.

This is my app.js file. Not sure what I'm doing wrong. Thanks.

import React, { useEffect, useState } from "react";
import {
  ActivityIndicator,
  FlatList,
  StyleSheet,
  View,
  Text,
  Button,
} from "react-native";

import Clipboard from '@react-native-community/clipboard';

const App: () => React$Node = () => {

  
  const [isLoading, setLoading] = useState(true);
  const [data, setData] = useState([]);
  const [refetch, setRefetch] = useState(false);

  const [copiedText, setCopiedText] = useState('');

  const copyToClipboard = () => {
    Clipboard.setString({item.content});
  };

  const fetchCopiedText = async () => {
    const text = await Clipboard.getString();
    setCopiedText(text);
  };

  useEffect(() => {
    fetch("https://exampleapi.com/")
      .then((response) => response.json())
      .then((json) => setData(json))
      .catch((error) => console.error(error))
      .finally(() => setLoading(false));
  }, [refetch]);
  

  return (
    <>
      <View style={styles.container}>
        {isLoading ? (
          <ActivityIndicator />
        ) : (
          <FlatList
            data={data}
            keyExtractor={({ id }, index) => id}
            renderItem={({ item }) => (
              <Text style={styles.content}>❝ {item.content} ❞</Text>
            )}
          />
        )}
      </View>
      <View>
        <View style={styles.buttonStyle}>
          <Button
                    title="New"
                    onPress={() => setRefetch(!refetch)}
                    style={styles.buttonCopy}
                    color="#134074"
                  />
        </View>
        <View style={styles.buttonStyle}>
          <Button
                  title="Copy"
                  onPress={() => this.copyToClipboard}
                  style={styles.buttonCopy}
                  color="#aa4465"
                />
        </View>
      </View>
    </>
  );
};


const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    backgroundColor: "#001524",
    padding: 30,
    flexDirection: "row",
    alignItems: "center"
  },
  content: {
    fontSize: 25,
    textAlign: "left",
    color: "#ffecd1",
=    padding: 15
  },
  QuotesMark: {
    color: "#ffffff",
    fontSize: 30
  },
  buttonStyle: {
    padding: 10,
    alignItems: "center",
    backgroundColor: "#001524",
  }
});

export default App;

Upvotes: 0

Views: 3529

Answers (3)

Pratik Khadka
Pratik Khadka

Reputation: 958

For those who are here using expo and are having issues while using '@react-native-community/clipboard'. Switch to expo-clipboard refer to this documentation

Upvotes: 2

Ketan Ramteke
Ketan Ramteke

Reputation: 10655

Output:

enter image description here

Here is the full working example, here when you click on the FlatList Item, that that item will be copied to the clipboard. I have converted the Copy button to the Paste button to show paste functionality.

One more suggestion if you are using Expo for making app, @react-native-community/clipboard is still not supported by Expo so use Clipboard provided in react-native libraries instead, that's what I have done in the following example.

import React, { useEffect, useState } from 'react';
import {
  ActivityIndicator,
  FlatList,
  StyleSheet,
  View,
  Text,
  Button,
  TouchableOpacity,
  TextInput,
  Clipboard,
} from 'react-native';

const App = () => {
  const [isLoading, setLoading] = useState(true);
  const [data, setData] = useState([]);
  const [refetch, setRefetch] = useState(false);
  const [selectedText, setSelectedText] = useState('');

  const [copiedText, setCopiedText] = useState(
    'Nothing to show, copy by clicking on FlatList Text, and paste it by clicking Paste button'
  );

  const copyToClipboard = (text) => {
    Clipboard.setString(text);
    console.log('copied to Clipboard');
    fetchCopiedText();
    console.log('copied text: ', copiedText);
  };

  const fetchCopiedText = async () => {
    const text = await Clipboard.getString();
    setCopiedText(text);
  };

  useEffect(() => {
    fetch('https://jsonplaceholder.typicode.com/posts')
      .then((response) => response.json())
      .then((json) => setData(json))
      .catch((error) => console.error(error))
      .finally(() => setLoading(false));
  }, [refetch]);

  return (
    <>
      <View style={styles.container}>
        <TextInput
          style={{
            padding: 10,
            backgroundColor: 'white',
            width: 300,
            color: 'black',
            height: 100,
          }}
        />
        {isLoading ? (
          <ActivityIndicator />
        ) : (
          <FlatList
            data={data}
            keyExtractor={({ id }, index) => id}
            renderItem={({ item }) => (
              <TouchableOpacity
                onPress={() => {
                  Clipboard.setString(item.title);
                  console.log('selected text:', selectedText);
                }}>
                <Text style={styles.content}>❝ {item.title} ❞</Text>
              </TouchableOpacity>
            )}
          />
        )}
      </View>
      <View style={{ width: 300, height: 100 }}>
        <Text>{copiedText}</Text>
      </View>
      <View>
        <View style={styles.buttonStyle}>
          <Button
            title="New"
            onPress={() => setRefetch(!refetch)}
            style={styles.buttonCopy}
            color="#134074"
          />
        </View>
        <View style={styles.buttonStyle}>
          <Button
            title="Paste"
            onPress={() => {
              fetchCopiedText();
            }}
            style={styles.buttonCopy}
            color="#aa4465"
          />
        </View>
      </View>
    </>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    backgroundColor: '#001524',
    padding: 30,
    flexDirection: 'column',
    alignItems: 'center',
  },
  content: {
    fontSize: 25,
    textAlign: 'left',
    color: '#ffecd1',
  },
  QuotesMark: {
    color: '#ffffff',
    fontSize: 10,
  },
  buttonStyle: {
    padding: 10,
    alignItems: 'center',
    backgroundColor: '#001524',
  },
});

export default App;

Working Expo Snack Demo

Upvotes: 2

Alexandr Sargsyan
Alexandr Sargsyan

Reputation: 724

From documentation:

 const copyToClipboard = () => {
    Clipboard.setString('hello world');
  };

It receives string rather than object.

Change your code

 const copyToClipboard = () => {
    Clipboard.setString({item.content});
  };

to this

const copyToClipboard = () => {
    Clipboard.setString(item.content);
  };

Upvotes: 1

Related Questions