如何将React-Native中的字符串更改为组件?

时间:2017-03-07 15:59:43

标签: react-native

我有一个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,但它的文档难以理解,并且表现不佳。

5 个答案:

答案 0 :(得分:1)

将其设置为您所在州的一部分(例如this.state.str)。在构造函数中,为其指定一个默认值(例如this.state = {str: "test"})。然后在执行提取的函数中,执行setState更改值(例如this.setState({str: response}))。最后,在渲染中,执行以下操作:

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

答案 1 :(得分:1)

您可以创建一个函数,将您获得的响应的内部html转换为RN Text元素。

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>

答案 2 :(得分:0)

  var str = <Text>test</Text>;

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

答案 3 :(得分:0)

不幸的是,标记需要在编译时合并,因为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 :(得分:0)

我的要求类似,使用任意组件制作动态屏幕,具体取决于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>
        );

很容易声明您希望使用的所有组件,就像我使用文本和链接一样,并为它们设置样式。