【问题标题】:How to change a string in React-Native into a Component?如何将 React-Native 中的字符串更改为组件?
【发布时间】:2017-07-27 22:13:31
【问题描述】:

我有一个var str = '<Text> something </Text>',我可以把它渲染成一个组件吗?

我尝试了以下方法,但它不起作用:(

var str = '<Text>test</Text>'
    render(){
        return(
            <Text>{str}</Text>
        )
   }

有没有办法做到这一点,类似于 React 中的dangerouslySetInnerHTML

在我的项目中,我通过 fetch 获取 json 就像

{
   content:'<p>example</p>'
}

我想用正则表达式将html元素p或者其他的替换成Text等等,但是结果是一个字符串。

我也尝试了react-native-html-render,但它的文档难以理解且性能不佳。

【问题讨论】:

标签: react-native


【解决方案1】:

我的要求是类似的,根据 JSON 服务器响应制作带有任意组件的动态屏幕。这是我所做的:

const blockContent = [
  {
    type: 'text',
    content: 'Some title',
    size: 20,
    color: 'black',
    wrapperPadding: 10
  },
    {
      type: 'text',
      wrapperPadding: 10,
      size: 16,
      color: 'red',
      content: 'Some text. Some text. Some text. Some text. Some text. '
    },
    {
      type: 'text',
      wrapperPadding: 10,
      size: 16,
      color: 'red',
      content: 'Some text. Some text. Some text. Some text. Some text. '
    },
    {
      type: 'link',
      content: 'Some link',
      size: 16,
      color: 'blue',
      wrapperPadding: 10,
      url: 'http://www.google.com'
    }
];

    class CustomBlock extends Component {

      openURL (url) {
        Linking.openURL(url).catch(err => console.error('An error occurred', err));
      }

      render () {
        return (
            <View style={styles.container}>
            {blockContent.map((item) => {
              switch (item.type) {
                case 'text':
                  return (
                    <View style={{padding: item.wrapperPadding}}>
                      <Text style={{fontSize: item.size, color: item.color}}>{item.content}</Text>
                    </View>
                  );
                case 'link':
                  return (
                    <TouchableHighlight style={{padding: item.wrapperPadding}} underlayColor="lightgrey" onPress={this.openURL.bind(this, item.url)}>
                      <Text style={{fontSize: item.size, color: item.color}}>{item.content}</Text>
                    </TouchableHighlight>
                  );
              }
             })}
            </View>
        );

声明您希望使用的所有组件(就像我对文本和链接所做的那样)以及设置它们的样式非常容易。

【讨论】:

    【解决方案2】:

    您可以创建一个函数,将您收到的响应的内部 html 转换为 RN 文本元素。

    var str = '<p>something here</p>'
    
    var convertToText = (response) => {
      var text = response.split(/[^A-Za-z]/).filter(x => x !== '').slice(1, -1).join(' ') //gives "something here";
      return <Text>text</Text>;
    }
    
    convertToText(str) === <Text>something here</Text>
    

    【讨论】:

    • 谢谢,我已经编辑了我的问题,您能帮我解决这个问题吗?再次感谢。
    • 更新了我的答案,您基本上可以使用此功能将它们转换为文本元素,但如果您需要根据响应中的内容使用不同的元素,那么您需要添加更多配置。
    • 实际上我意识到这仅适用于一个单词元素,只是更新它以处理任意数量的单词。
    【解决方案3】:

    不幸的是,tag 需要在编译时合并,因为 JSX 被转译为 React.createElement 调用。或者您可以自己编写React.createElement 调用。

    例如,您可以创建一个解析器,以便在您的服务器响应中遍历 JSX 树。类似的东西

    function parseResponseIntoJSXTree (string) {
      // very psuedo example:
      var type = parseJSXTag(string) // produces `Text`
      var props = parseJSXTagProps(string) // produce any attribute=values
      var innerContent = parseJSXContent(string) // produces 'something'
      return React.createElement(type, props, children)
    }
    

    这只是表面问题,因为如果有比根节点更深的子元素,您需要遍历树。

    想要我可怕的、可怕的答案吗? 在你的包中包含babel 并执行:

    var renderableContent = require('babel-core', {presets: ['react-native'])
      .transform('<Text>something</Text>')
    

    注意 - 我强烈反对这样做,但它在技术上会起作用,除非 babel 需要运行时中不存在的节点依赖项(可能)。

    【讨论】:

    • 谢谢!但是对我来说编写解析似乎有点困难。还有你说的可怕的答案......它可能是一种值得考虑的有用方式。再次感谢!
    【解决方案4】:

    将其设置为您的状态的一部分(例如,this.state.str)。在你的构造函数中,给它一个默认值(例如,this.state = {str: "test"})。然后在执行获取的函数中,执行setState 以更改值(例如,this.setState({str: response}))。最后,在你的渲染中,这样做:

    render() {
        return (
          <View style={styles.container}>
            <Text>{this.state.str}</Text>
          </View>
        );
      }
    

    【讨论】:

      【解决方案5】:
        var str = <Text>test</Text>;
      
        render() {
          return (
            <View style={styles.container}>
              {str}
            </View>
          );
        }
      

      【讨论】:

      • thx,但实际上这是一个获取的响应,所以我不能像你说的那样设置 str...
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-20
      • 2019-10-17
      • 1970-01-01
      • 2020-09-14
      • 2018-02-12
      • 2021-08-20
      相关资源
      最近更新 更多