Jak wyświetlić hiperłącze w aplikacji React Native?

110

Jak wyświetlić hiperłącze w aplikacji React Native?

na przykład

<a href="https://google.com>Google</a> 
Will Chu
źródło
2
Rozważ dodanie większej liczby tagów, takich jak „javascript”, aby przyciągnąć więcej uwagi użytkowników. Ale nie uogólniaj swoich postów, dodając tagi, takie jak „kodowanie” itp.
Matt C
@MattC Twierdziłbym, że dodanie „javascript” jest zbyt ogólne.
ryanwebjackson

Odpowiedzi:

236

Coś takiego:

<Text style={{color: 'blue'}}
      onPress={() => Linking.openURL('http://google.com')}>
  Google
</Text>

używając Linkingmodułu dołączonego do React Native.

Philipp von Weitershausen
źródło
1
Jeśli potrzebujesz wartości dynamicznej, możesz użyć czegoś takiego jak this.props.urlzamiast 'http://google.com'(bez nawiasów klamrowych)
Elon Zito,
@philipp rzuca mi błąd m 'nie można znaleźć zmiennej Linking'
Devansh sadhotra
2
@devanshsadhotra czy masz import { Linking } from 'react-native';w swoim dokumencie?
Eric Phillips
2
Możesz również osadzić elementy <Text>, aby połączony tekst mógł być częścią tekstu nadrzędnego:<Text>Some paragraph <Text onPress=...>with a link</Text> inside</Text>
pstanton
4
LinkingIOS został zdeprecjonowany, użyj linkowania.
jasonleonhard
26

Wybrana odpowiedź dotyczy tylko iOS. W przypadku obu platform możesz użyć następującego składnika:

import React, { Component, PropTypes } from 'react';
import {
  Linking,
  Text,
  StyleSheet
} from 'react-native';

export default class HyperLink extends Component {

  constructor(){
      super();
      this._goToURL = this._goToURL.bind(this);
  }

  static propTypes = {
    url: PropTypes.string.isRequired,
    title: PropTypes.string.isRequired,
  }

  render() {

    const { title} = this.props;

    return(
      <Text style={styles.title} onPress={this._goToURL}>
        >  {title}
      </Text>
    );
  }

  _goToURL() {
    const { url } = this.props;
    Linking.canOpenURL(url).then(supported => {
      if (supported) {
        Linking.openURL(this.props.url);
      } else {
        console.log('Don\'t know how to open URI: ' + this.props.url);
      }
    });
  }
}

const styles = StyleSheet.create({
  title: {
    color: '#acacac',
    fontWeight: 'bold'
  }
});
Kuf
źródło
3
Wybrana odpowiedź działała dobrze dla mnie w systemie Android (RN 35).
Pedram
2
@JacobLauritzen teraz jest tak samo po tym, jak ktoś skopiował moją odpowiedź: / stackoverflow.com/posts/30540502/revisions
Kuf
21

Aby to zrobić, zdecydowanie rozważyłbym umieszczenie Textkomponentu w TouchableOpacity. Kiedy TouchableOpacityzostanie dotknięty, zanika (staje się mniej matowy). Daje to użytkownikowi natychmiastową informację zwrotną po dotknięciu tekstu i zapewnia lepszą obsługę.

Możesz użyć onPresswłaściwości na stronie, TouchableOpacityaby utworzyć łącze:

<TouchableOpacity onPress={() => Linking.openURL('http://google.com')}>
  <Text style={{color: 'blue'}}>
    Google
  </Text>
</TouchableOpacity>
Tom Aranda
źródło
13

Dokumentacja React Native sugeruje użycie Linking :

Odniesienie

Oto bardzo podstawowy przypadek użycia:

import { Linking } from 'react-native';

const url="https://google.com"

<Text onPress={() => Linking.openURL(url)}>
    {url}
</Text>

Możesz użyć notacji funkcjonalnej lub klasowej, wybór dealera.

jasonleonhard
źródło
LinkingIOS został zdeprecjonowany, użyj linkowania.
jasonleonhard
4

Użyj React Native Hyperlink ( <A>tag natywny ):

Zainstalować:

npm i react-native-a

import:

import A from 'react-native-a'

Stosowanie:

  1. <A>Example.com</A>
  2. <A href="example.com">Example</A>
  3. <A href="https://example.com">Example</A>
  4. <A href="example.com" style={{fontWeight: 'bold'}}>Example</A>
Khalil Laleh
źródło
3

Kolejną pomocną uwagą, którą należy dodać do powyższych odpowiedzi, jest dodanie stylu flexbox. Dzięki temu tekst pozostanie w jednej linii i nie będzie się nakładał na ekran.

 <View style={{ display: "flex", flexDirection: "row", flex: 1, flexWrap: 'wrap', margin: 10 }}>
  <Text>Add your </Text>
  <TouchableOpacity>
    <Text style={{ color: 'blue' }} onpress={() => Linking.openURL('https://www.google.com')} >
         link
    </Text>
   </TouchableOpacity>
   <Text>here.
   </Text>
 </View>
Stephanieraymos
źródło
1

Jeśli chcesz robić linki i inne typy tekstu sformatowanego, bardziej wszechstronnym rozwiązaniem jest użycie React Native HTMLView .

Eliot
źródło
1
Chociaż ten link może odpowiedzieć na pytanie, lepiej jest zawrzeć tutaj zasadnicze części odpowiedzi i podać link do odniesienia. Odpowiedzi zawierające tylko łącze mogą stać się nieprawidłowe, jeśli połączona strona ulegnie zmianie. - Z recenzji
Ari0nhh
@ Ari0nhh Cofnąłem usunięcie pytania, ponieważ był to jedyny sposób, w jaki mogłem odpowiedzieć na Twój komentarz. Istnieje wiele precedensów w SO, gdzie wysoko sklasyfikowana odpowiedź jest po prostu linkiem do dobrej biblioteki. Inne odpowiedzi obejmują już prostą implementację. Przypuszczam, że mógłbym zamieścić to ponownie jako komentarz do pierwotnego pytania, ale uważam to za prawdziwą odpowiedź. Pozostawienie linku w tym miejscu to przynajmniej okruch dla przyszłych poszukiwaczy, jeśli ludzie chcą go edytować i ulepszać za pomocą lepszych przykładów, przynajmniej teraz jest od czego zacząć.
Eliot
1

Pomyślałem, że podzielę się moim hackerskim rozwiązaniem z każdym, kto teraz odkrywa ten problem z osadzonymi linkami w ciągu. Próbuje wstawić linki , renderując je dynamicznie za pomocą dowolnego ciągu, który jest do niego wprowadzany.

Możesz go dostosować do swoich potrzeb. Działa dla naszych celów, takich jak:

To jest przykład tego, jak https://google.com .

Zobacz to na Gist:

https://gist.github.com/Friendly-Robot/b4fa8501238b1118caaa908b08eb49e2

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

export default function renderHyperlinkedText(string, baseStyles = {}, linkStyles = {}, openLink) {
  if (typeof string !== 'string') return null;
  const httpRegex = /http/g;
  const wwwRegex = /www/g;
  const comRegex = /.com/g;
  const httpType = httpRegex.test(string);
  const wwwType = wwwRegex.test(string);
  const comIndices = getMatchedIndices(comRegex, string);
  if ((httpType || wwwType) && comIndices.length) {
    // Reset these regex indices because `comRegex` throws it off at its completion. 
    httpRegex.lastIndex = 0;
    wwwRegex.lastIndex = 0;
    const httpIndices = httpType ? 
      getMatchedIndices(httpRegex, string) : getMatchedIndices(wwwRegex, string);
    if (httpIndices.length === comIndices.length) {
      const result = [];
      let noLinkString = string.substring(0, httpIndices[0] || string.length);
      result.push(<Text key={noLinkString} style={baseStyles}>{ noLinkString }</Text>);
      for (let i = 0; i < httpIndices.length; i += 1) {
        const linkString = string.substring(httpIndices[i], comIndices[i] + 4);
        result.push(
          <Text
            key={linkString}
            style={[baseStyles, linkStyles]}
            onPress={openLink ? () => openLink(linkString) : () => Linking.openURL(linkString)}
          >
            { linkString }
          </Text>
        );
        noLinkString = string.substring(comIndices[i] + 4, httpIndices[i + 1] || string.length);
        if (noLinkString) {
          result.push(
            <Text key={noLinkString} style={baseStyles}>
              { noLinkString }
            </Text>
          );
        }
      }
      // Make sure the parent `<View>` container has a style of `flexWrap: 'wrap'`
      return result;
    }
  }
  return <Text style={baseStyles}>{ string }</Text>;
}

function getMatchedIndices(regex, text) {
  const result = [];
  let match;
  do {
    match = regex.exec(text);
    if (match) result.push(match.index);
  } while (match);
  return result;
}
Przyjazny robot
źródło
1

Importuj Łączenie modułu z React Native

import { TouchableOpacity, Linking } from "react-native";

Spróbuj:-

<TouchableOpacity onPress={() => Linking.openURL('http://Facebook.com')}>
     <Text> Facebook </Text>     
</TouchableOpacity>
Parveen Chauhan
źródło