Reputation: 1893
Is it possible to dynamically create and add view components in React Native? For example, firstly I have only empty screen and information of all views come from server in JSON, and then it is need to generate them on the screen. For example - application getting json from server. This json describes the screen that have to be builded:
{
"type": "linearlayout",
"subviews": [{
"type": "text",
"fields": {
"text": "This is text field"
},
"styles": {
"color": "",
"textSize": 14
}
}, {
"type": "button",
"fields": {
"text": "JUST BUTTON"
},
"transition": {
"name": "http://www.link.com"
}
}, {
"type": "text",
"fields": {
"text": "This is another text field"
},
"styles": {
"color": "",
"textSize": 18
}
}]
}
So, by that JSON I need dynamically views building in React Native. But I can't see any ability to write JS code inside JSX - only static views and dynamically changing of props
Upvotes: 20
Views: 29608
Reputation: 186
Here is another approach:-
import { StatusBar } from 'expo-status-bar';
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
const renderObject = {
type : "View",
children : [
{
type: "View",
styles: {
backgroundColor: "orange",
flex:1,
justifyContent:"center",
alignItems: "center"
},
children: [
{
type: "Text",
styles: {
color: "yellow",
fontSize: 20
},
text: "Hello"
},
{
type: "View",
styles: {
backgroundColor: "red",
width: 100,
height: 5,
marginTop: 10
},
children: []
}
]
},
{
type: "View",
styles: {
flex:1,
justifyContent:"center",
alignItems: "center"
},
children: [
{
type: "Text",
styles: {
color: "red",
fontSize: 40
},
text: "Hello"
}
]
},
{
type: "View",
styles: {
flex:1,
justifyContent:"center",
alignItems: "center",
backgroundColor: "green"
},
children: [
{
type: "Text",
styles: {
color: "white",
fontSize: 80
},
text: "Hello"
}
]
}
],
styles: {
flex:1
}
}
const CustomComp = (props) => {
const {type} = props;
if(type == "View"){
const {styles, children} = props;
return <View style={styles}>{children.map((item) => CustomComp(item))}</View>
} else if(type == "Text") {
const {styles, text} = props;
return <Text style={styles} >{text}</Text>
}
}
export default function App() {
return (
<View style={styles.container}>
{CustomComp(renderObject)}
<StatusBar style="auto" />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
justifyContent: 'center',
},
});
You can find the full code on this Repo.
Upvotes: 4
Reputation: 1740
React docs (and by extension it could be done with ReactNative too) show how to choose the component type at runtime:
import React from 'react';
import { PhotoStory, VideoStory } from './stories';
const components = {
photo: PhotoStory,
video: VideoStory
};
function Story(props) {
const SpecificStory = components[props.storyType];
return <SpecificStory story={props.story} />;
}
Doing so, you could just only need to walk on your JSON tree and just create the ReactNative components, using the components
object as a mapping between the type defined in the JSON tree and their constructors.
Upvotes: 6
Reputation: 3469
Yes this is possible. Assume that you retrieve your JSON data successfully and save it to some state then in your render function you can use it like that;
render() {
var productList = [];
this.state.data.products.forEach(function (tmpProduct) {
productList.push(
<View style={cardView} key={tmpProduct.id}>
<Grid style={upperGrid}>
<Col style={{flex: 0.5}}>
<Thumbnail
source={require('../../../images/sample-image.png')}
style={itemThumb}>
</Col>
<Col>
<Text style={cardItemHeader} numberOfLines={2}>{tmpProduct.title}</Text>
<Text style={cardItemBody} numberOfLines={2}>{tmpProduct.description}</Text>
</Col>
</Grid>
</View>
);
}.bind(this));
return (
<Container theme={theme}>
<Image source={require('../../../images/grad-bg.png')} style={background} >
<Content style={scrollContent}>
{productList}
</Content>
</Image>
</Container>
)
}
I hope this code piece give you an idea. You can adapt it to your case.
Upvotes: 16
Reputation: 1713
One of the benefits of using react native (vs webview) is that your users won't be staring at empty screens when the app is loading data. If you return all views from server, then it works like web page. I have done something like that before. Believe me that's not the best UX. Ideally json response should only return data. Then client can be built with any framework (react native, iOS or Android native) and they share the same API endpoints.
Upvotes: -1
Reputation: 1977
Yes it is possible to dynamically create components in React Native based on data you retrieve from the server.
However, if you are wanting the app to check for the latest JS code (including new components/views) without requiring an update through app store, you could use something like code-push. https://microsoft.github.io/code-push/
Your question is somewhat vague so if I misunderstood then possibly you could give an example 'information of all views'.
Upvotes: 1