เราจะแสดงไฮเปอร์ลิงก์ใน React Native App ได้อย่างไร?


118

ฉันจะแสดงไฮเปอร์ลิงก์ในแอป React Native ได้อย่างไร

เช่น

<a href="https://google.com>Google</a> 

2
ลองเพิ่มแท็กอื่น ๆ เช่น 'javascript' เพื่อดึงดูดความสนใจจากผู้ใช้มากขึ้น แต่อย่าทำให้โพสต์ของคุณกว้างเกินไปโดยการเพิ่มแท็กเช่น 'coding' เป็นต้น
Matt C

1
@MattC ฉันขอเถียงว่าการเพิ่ม 'javascript' นั้นกว้างเกินไป
ryanwebjackson

คำตอบ:


260

สิ่งนี้:

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

โดยใช้Linkingโมดูลที่มาพร้อมกับ React Native


1
หากคุณต้องการค่าไดนามิกคุณสามารถใช้สิ่งที่ต้องการthis.props.urlแทนได้'http://google.com'(ไม่จำเป็นต้องจัดฟัน)
Elon Zito

@philipp มันทำให้ฉันเกิดข้อผิดพลาด 'ไม่พบการเชื่อมโยงตัวแปร'
Devansh sadhotra

2
@devanshsadhotra คุณมีimport { Linking } from 'react-native';ในเอกสารไหม
Eric Phillips

2
คุณสามารถฝังองค์ประกอบ <Text> ด้วยเพื่อให้ข้อความที่เชื่อมโยงเป็นส่วนหนึ่งของข้อความหลัก:<Text>Some paragraph <Text onPress=...>with a link</Text> inside</Text>
pstanton

4
LinkingIOS คิดค่าเสื่อมราคาแล้วให้ใช้ Linking
jasonleonhard

28

คำตอบที่เลือกหมายถึง iOS เท่านั้น สำหรับทั้งสองแพลตฟอร์มคุณสามารถใช้ส่วนประกอบต่อไปนี้:

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'
  }
});

3
คำตอบที่เลือกใช้งานได้ดีสำหรับฉันใน Android (RN 35)
Pedram

2
@JacobLauritzen ตอนนี้ก็เหมือนกันหลังจากมีคนคัดลอกคำตอบของฉัน: / stackoverflow.com/posts/30540502/revisions
Kuf

21

ในการทำเช่นนี้ฉันจะพิจารณาอย่างยิ่งว่าจะห่อTextส่วนประกอบในไฟล์TouchableOpacity. เมื่อTouchableOpacityสัมผัสจะจางลง (ทึบแสงน้อยลง) สิ่งนี้ทำให้ผู้ใช้ตอบรับทันทีเมื่อสัมผัสข้อความและมอบประสบการณ์การใช้งานที่ดีขึ้น

คุณสามารถใช้onPressคุณสมบัติบนTouchableOpacityเพื่อทำให้ลิงค์เกิดขึ้น:

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

13

React Native documentation แนะนำให้ใช้Linking:

ข้อมูลอ้างอิง

นี่คือกรณีการใช้งานขั้นพื้นฐาน:

import { Linking } from 'react-native';

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

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

คุณสามารถใช้สัญกรณ์ส่วนประกอบที่ใช้งานได้หรือคลาสทางเลือกของตัวแทนจำหน่าย


LinkingIOS คิดค่าเสื่อมราคาแล้วให้ใช้ Linking
jasonleonhard

4

ใช้ React Native Hyperlink (Native <A>tag):

ติดตั้ง:

npm i react-native-a

นำเข้า:

import A from 'react-native-a'

การใช้งาน:

  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>

4

หมายเหตุที่เป็นประโยชน์อีกประการหนึ่งในการเพิ่มคำตอบข้างต้นคือการเพิ่มสไตล์เฟล็กบ็อกซ์ การดำเนินการนี้จะทำให้ข้อความอยู่ในบรรทัดเดียวและตรวจสอบให้แน่ใจว่าข้อความไม่ทับซ้อนกันบนหน้าจอ

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

2

สำหรับ React Native มีไลบรารีสำหรับเปิดไฮเปอร์ลิงก์ในแอพ https://www.npmjs.com/package/react-native-hyperlink

นอกจากนี้ฉันคิดว่าคุณจะต้องตรวจสอบ url และแนวทางที่ดีที่สุดคือ Regex https://www.npmjs.com/package/url-regex


หากคุณกำลังสร้างสำหรับ ios SVC เป็นแนวทางที่ดีกว่าในการนำไปใช้แทนการเชื่อมโยง (เพื่อเปิดในเบราว์เซอร์ Safari) github.com/naoufal/react-native-safari-view
rajaishwary

2

นำเข้าการเชื่อมโยงโมดูลจาก React Native

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

ลองมัน:-

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

1

หากคุณต้องการที่จะทำการเชื่อมโยงและประเภทอื่น ๆ ของข้อความที่อุดมไปด้วยโซลูชั่นที่ครอบคลุมมากขึ้นคือการใช้งานตอบสนองพื้นเมือง HTMLView


1
แม้ว่าลิงก์นี้อาจตอบคำถามได้ แต่ควรรวมส่วนสำคัญของคำตอบไว้ที่นี่และระบุลิงก์เพื่อการอ้างอิง คำตอบแบบลิงก์เท่านั้นอาจไม่ถูกต้องหากหน้าที่เชื่อมโยงเปลี่ยนไป - จากรีวิว
Ari0nhh

@ Ari0nhh ฉันยกเลิกการลบคำถามเพราะเป็นวิธีเดียวที่ฉันจะตอบกลับความคิดเห็นของคุณได้ มีตัวอย่างมากมายเกี่ยวกับ SO ซึ่งคำตอบที่ได้รับการจัดอันดับสูงเป็นเพียงลิงก์ไปยังห้องสมุดที่ดี นอกจากนี้คำตอบอื่น ๆ ยังครอบคลุมการนำไปใช้งานง่ายๆ ฉันคิดว่าฉันสามารถโพสต์สิ่งนี้ใหม่เป็นความคิดเห็นของคำถามเดิม แต่ฉันคิดว่ามันเป็นคำตอบที่แท้จริง และการออกจากลิงก์ที่นี่อย่างน้อยก็เป็นส่วนสำคัญสำหรับผู้ค้นหาในอนาคตหากผู้คนต้องการแก้ไขและปรับปรุงด้วยตัวอย่างที่ดีขึ้นอย่างน้อยตอนนี้ก็มีจุดเริ่มต้น
Eliot

1

แค่คิดว่าฉันจะแบ่งปันวิธีแก้ปัญหาแฮ็กกับใครก็ตามที่พบปัญหานี้ด้วยลิงก์ที่ฝังอยู่ภายในสตริง มันพยายามที่จะอินไลน์ลิงก์โดยการแสดงผลแบบไดนามิกพร้อมกับสตริงที่เคยป้อนเข้าไป

โปรดอย่าลังเลที่จะปรับแต่งตามความต้องการของคุณ มันทำงานตามวัตถุประสงค์ของเราดังนี้:

นี่คือตัวอย่างของลักษณะที่https://google.comจะปรากฏ

ดูใน 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;
}

1

คุณสามารถใช้คุณสมบัติการเชื่อมโยง <Text style = {{color: 'skyblue'}} onPress = {() => Linking.openURL ('http://yahoo.com')}> Yahoo

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.