¿Cómo se muestra un hipervínculo en la aplicación React Native?

110

¿Cómo muestro un hipervínculo en una aplicación React Native?

p.ej

<a href="https://google.com>Google</a> 
Will Chu
fuente
2
Considere agregar más etiquetas como "javascript" para llamar más la atención de los usuarios. Pero no generalice demasiado sus publicaciones agregando etiquetas como 'codificación', etc.
Matt C
@MattC Yo diría que agregar 'javascript' es demasiado general.
ryanwebjackson

Respuestas:

233

Algo como esto:

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

usando el Linkingmódulo que se incluye con React Native.

Philipp von Weitershausen
fuente
1
Si necesita un valor dinámico, puede usar algo como this.props.urlen lugar de 'http://google.com'(no se necesitan llaves)
Elon Zito
@philipp me está lanzando un error m 'no puedo encontrar el
enlace
2
@devanshsadhotra tienes import { Linking } from 'react-native';en tu documento?
Eric Phillips
2
También puede incrustar elementos <Text> para que el texto vinculado pueda ser una parte del texto principal:<Text>Some paragraph <Text onPress=...>with a link</Text> inside</Text>
pstanton
4
LinkingIOS se ha depreciado, use Linking.
Jasonleonhard
26

La respuesta seleccionada se refiere solo a iOS. Para ambas plataformas, puede utilizar el siguiente 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
fuente
3
La respuesta seleccionada funcionó bien para mí en Android (RN 35).
Pedram
2
@JacobLauritzen bueno, ahora es lo mismo después de que alguien copiara mi respuesta: / stackoverflow.com/posts/30540502/revisions
Kuf
21

Para hacer esto, consideraría encarecidamente envolver un Textcomponente en un archivo TouchableOpacity. Cuando TouchableOpacityse toca a, se desvanece (se vuelve menos opaco). Esto le da al usuario una respuesta inmediata al tocar el texto y proporciona una experiencia de usuario mejorada.

Puede usar la onPresspropiedad en el TouchableOpacitypara hacer que el enlace suceda:

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

La documentación de React Native sugiere usar Linking:

Referencia

Aquí hay un caso de uso muy básico:

import { Linking } from 'react-native';

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

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

Puede utilizar la notación de componentes funcionales o de clase, a elección del distribuidor.

Jasonleonhard
fuente
LinkingIOS se ha depreciado, use Linking.
jasonleonhard
4

Utilice React Native Hyperlink (nativo <A> etiqueta ):

Instalar en pc:

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

Otra nota útil para agregar a las respuestas anteriores es agregar algunos estilos de flexbox. Esto mantendrá el texto en una línea y se asegurará de que el texto no se superponga a la pantalla.

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

Si desea crear enlaces y otros tipos de texto enriquecido, una solución más completa es usar React Native HTMLView .

Eliot
fuente
1
Si bien este enlace puede responder a la pregunta, es mejor incluir las partes esenciales de la respuesta aquí y proporcionar el enlace como referencia. Las respuestas de solo enlace pueden dejar de ser válidas si cambia la página enlazada. - De la crítica
Ari0nhh
@ Ari0nhh Recuperé la pregunta porque era la única forma en que podía responder a su comentario. Hay muchos precedentes en SO donde una respuesta altamente clasificada es simplemente un enlace a una buena biblioteca. Además, otras respuestas ya cubren una implementación simple. Supongo que podría volver a publicar esto como un comentario sobre la pregunta original, pero lo veo como una respuesta real. Y dejar el enlace aquí es al menos una migaja para los futuros buscadores, si la gente quiere editarlo y mejorarlo con mejores ejemplos, al menos ahora hay un lugar para comenzar.
Eliot
1

Solo pensé en compartir mi solución hacky con cualquiera que esté descubriendo este problema ahora con enlaces incrustados dentro de una cadena. Intenta alinear los enlaces renderizándolos dinámicamente con cualquier cadena que se le introduzca.

Siéntase libre de ajustarlo a sus necesidades. Está funcionando para nuestros propósitos como tal:

Este es un ejemplo de cómo aparecería https://google.com .

Véalo en 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;
}
Robot amigable
fuente
1

Importar Vincular el módulo desde React Native

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

Intentalo:-

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