我有一个 var str = '<Text> something </Text>'
,我可以将其渲染到一个组件吗?
我尝试了以下内容,但它不起作用:(
var str = '<Text>test</Text>'
render(){
return(
<Text>{str}</Text>
)
}
有什么方法可以做到这一点,类似于react中的dangerouslySetInnerHTML
?
在我的项目中,我像
一样通过获取JSON{
content:'<p>example</p>'
}
我想将HTML元素p
或其他元素替换为Text
,等等,但结果是字符串。
我也尝试了react-native-html-render
,但文档是难以理解的,并且表现不佳。
您可以创建一个函数,该函数将响应的内部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>
将其设置为状态的一部分(例如this.state.str
)。在您的构造函数中,给它一个默认值(例如this.state = {str: "test"}
)。然后,在您的函数中进行提取,请执行setState
以更改值(例如this.setState({str: response})
)。最后,在您的渲染中,执行此操作:
render() {
return (
<View style={styles.container}>
<Text>{this.state.str}</Text>
</View>
);
}
var str = <Text>test</Text>;
render() {
return (
<View style={styles.container}>
{str}
</View>
);
}
不幸的是, 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
需要在运行时不存在的节点依赖项(可能)。
我的要求相似,以任意组件制作动态屏幕,具体取决于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>
);
很容易声明您期望像我对文本和链接一样使用的所有组件,并为其设置样式。