Como exibir um hiperlink no aplicativo React Native?

110

Como exibo um hiperlink em um aplicativo React Native?

por exemplo

<a href="https://google.com>Google</a> 
Will Chu
fonte
2
Considere adicionar mais tags como 'javascript' para obter mais atenção dos usuários. Mas não generalize demais suas postagens adicionando tags como 'codificação', etc.
Matt C
@MattC Eu diria que adicionar 'javascript' é muito geral.
ryanwebjackson

Respostas:

233

Algo assim:

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

usando o Linkingmódulo que vem junto com o React Native.

Philipp von Weitershausen
fonte
1
Se precisar de um valor dinâmico, você pode usar algo como this.props.urlno lugar de 'http://google.com'(sem chaves necessárias)
Elon Zito
@philipp está gerando um
2
@devanshsadhotra você tem import { Linking } from 'react-native';em seu documento?
Eric Phillips
2
Você pode incorporar elementos <Text> também para que o texto vinculado possa ser uma parte do texto pai:<Text>Some paragraph <Text onPress=...>with a link</Text> inside</Text>
pstanton
4
LinkingIOS foi depreciado, use Linking.
jasonleonhard
26

A resposta selecionada refere-se apenas ao iOS. Para ambas as plataformas, você pode usar o seguinte componente:

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
fonte
3
A resposta selecionada funcionou bem para mim no Android (RN 35).
Pedram
2
@JacobLauritzen bem, agora é o mesmo depois que alguém copiou minha resposta: / stackoverflow.com/posts/30540502/revisions
Kuf
21

Para fazer isso, eu consideraria fortemente envolver um Textcomponente em um TouchableOpacity. Quando um TouchableOpacityé tocado, ele desaparece (torna-se menos opaco). Isso fornece ao usuário um feedback imediato ao tocar no texto e fornece uma experiência de usuário aprimorada.

Você pode usar a onPresspropriedade no TouchableOpacitypara fazer o link acontecer:

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

A documentação do React Native sugere o uso de Linking:

Referência

Aqui está um caso de uso muito básico:

import { Linking } from 'react-native';

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

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

Você pode usar notação de componente funcional ou de classe, escolha do revendedor.

jasonleonhard
fonte
LinkingIOS foi depreciado, use Linking.
jasonleonhard de
4

Use React Native Hyperlink (Native <A>tag):

Instalar:

npm i react-native-a

importar:

import A from 'react-native-a'

Uso:

  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
fonte
3

Outra observação útil para adicionar às respostas acima é adicionar alguns estilos de flexbox. Isso manterá o texto em uma linha e garantirá que o texto não se sobreponha à tela.

 <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
fonte
1

Se você deseja fazer links e outros tipos de rich text, uma solução mais abrangente é usar React Native HTMLView .

Eliot
fonte
1
Embora este link possa responder à pergunta, é melhor incluir as partes essenciais da resposta aqui e fornecer o link para referência. As respostas somente com link podem se tornar inválidas se a página vinculada mudar. - Da avaliação
Ari0nhh
@ Ari0nhh Eu cancelei a pergunta porque foi a única maneira de responder ao seu comentário. Existem muitos precedentes no SO em que uma resposta bem classificada é simplesmente um link para uma boa biblioteca. Além disso, outras respostas já cobrem uma implementação simples. Suponho que poderia repassar isso como um comentário sobre a pergunta original, mas vejo isso como uma resposta real. E deixar o link aqui é pelo menos uma migalha para futuros buscadores, se as pessoas quiserem editá-lo e melhorá-lo com melhores exemplos, pelo menos agora há um lugar por onde começar.
Eliot
1

Apenas pensei em compartilhar minha solução hacky com qualquer pessoa que esteja descobrindo esse problema agora com links incorporados em uma string. Ele tenta incorporar os links ao renderizá-los dinamicamente com qualquer string que seja inserida nele.

Fique à vontade para ajustá-lo às suas necessidades. Está funcionando para nossos propósitos como:

Este é um exemplo de como https://google.com seria exibido.

Veja no 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;
}
Robô Amigável
fonte
1

Importar vinculando o módulo do React Native

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

Tente:-

<TouchableOpacity onPress={() => Linking.openURL('http://Facebook.com')}>
     <Text> Facebook </Text>     
</TouchableOpacity>
Parveen Chauhan
fonte