| 
需求
×
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册  
 
 
 实现
 支持文本插入,比如 xxx {product_name} xxx ,如果提供了product_name变量的值为feedback,则可以渲染出 xxx feedback xxx。
支持链接解析,比如 [baidu](https://www.baidu.com/),可以直接渲染成超链接的形式。
支持插入reactnode元素,比如 xxx {jump_node} xxx,且jump_node是一个reactnode元素,则可以将node节点插入到{}位置上。
 
 步骤:
 
 
 
 先解析链接, 返回如许子的数据布局。超链接返回url-text的对象,非超链接直接返回文本字符串
 复制代码export interface LinkPart {  text: string;  url?: string;  onClick?: string;}export type ParsedTextPart = string | LinkPart;[  {    text: 'baidu',    url: 'https://www.baidu.com/',  },  'other content',  'other content',];
 TextTemplate.tsx:
 遍历解析后的超链接数组,如果是对象,则渲染超链接;如果是字符串,继续解析
解析字符串,判定必要解析的{}里面的文本是否是纯文本,如果是纯文本,则直接Text渲染;如果是react元素,则渲染该元素
 
 parseLinkText.ts:复制代码import React, { ReactNode } from 'react';import { routeCenter } from '@shopeepay-rn/route-center';import { usePageContainerContext } from '@shopeepay-rn/page-container';import { StyleProp, Text, TextStyle, View, ViewStyle } from 'react-native';import { parseLinkText } from '../../utils';import styles from './styles';interface Props {  template: string;  // eg: {product_name:'spp', click_node:<Text></Text>}  replaceValueMap: Record<string, string | number | ReactNode>;  textStyle?: StyleProp<TextStyle>;  containerStyle?: StyleProp<ViewStyle>;}/** * 支持解析字符串、解析react元素、解析超链接 * @param template 需要解析的字符串 * @param replaceValueMap 需要替换的key-value,value支持字符串和react元素 * @param textStyle 字体样式 * @param containerStyle 容器样式 * @returns react元素 */export const TextTemplate = ({  template,  replaceValueMap,  textStyle,  containerStyle,}: Props) => {  const { rootTag } = usePageContainerContext();  const parseText = (text: string, index: number) => {    const result: React.ReactNode[] = [];    let lastIndex = 0;    text.replace(/{(\w+)}/g, (match: string, key: string, offset: number) => {      const replaceValue = replaceValueMap[key];      if (offset > lastIndex) {        // 未被匹配到的        result.push(          <Text key={index} style={textStyle}>            {text.substring(lastIndex, offset)}          </Text>        );      }      if (React.isValidElement(replaceValue)) {        // 需要替换的是reactnode元素        result.push(React.cloneElement(replaceValue, { key: index }));      } else if (typeof replaceValue === 'string') {        // 需要替换的是字符串        result.push(          <Text key={index} style={textStyle}>            {replaceValue}          </Text>        );      }      lastIndex = offset + match.length;      return '';    });    if (lastIndex < text.length) {      result.push(        <Text key={index} style={textStyle}>          {text.substring(lastIndex)}        </Text>      );    }    return result;  };  const parseTemplate = (text: string) => {    // 解析链接    const linkTexts = parseLinkText(text);    return linkTexts?.map((part, index) => {      return typeof part === 'string' ? (        // 对于字符串,需要解析 纯字符串 还是 reactnode元素        parseText(part, index)      ) : (        <Text          key={index}          style={styles.link}          onPress={() =>            routeCenter.navigateWeb(              part.url || '',              {                navbar: {                  title: part.text || '',                },              },              rootTag            )          }        >          {part.text}        </Text>      );    });  };  return (    <View style={[styles.textView, containerStyle]}>      <Text>{parseTemplate(template)}</Text>    </View>  );};
 使用复制代码export interface LinkPart {  text: string;  url?: string;  onClick?: string;}export type ParsedTextPart = string | LinkPart;const parseLinkText = (text: string): ParsedTextPart[] => {  const regex = /\[([^\]]+)\]\(([^)]+)\)/g;  const parts: ParsedTextPart[] = [];  let lastIndex = 0;  text.replace(    regex,    (match: string, p1: string, p2: string, offset: number) => {      if (offset > lastIndex) {        parts.push(text.substring(lastIndex, offset));      }      parts.push({ text: p1, url: p2 });      lastIndex = offset + match.length;      return '';    }  );  if (lastIndex < text.length) {    parts.push(text.substring(lastIndex));  }  return parts;};// FIXME: 添加 unit testexport { parseLinkText };
 
 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。复制代码<TextTemplate  template={"you can test the TextTemplate component, parse {string_text}, parse [baidu](https://www.baidu.com/) link, parse {click_node} to show popup"}  replaceValueMap={{string_text:"test string",click_node:<Text>other react node</Text>}}  textStyle={styles.titleText}/>
 |