是否可以在React Native中动态创建组件?

时间:2017-02-05 14:31:23

标签: dynamic react-native

是否可以在React Native中动态创建和添加视图组件? 例如,首先我只有空屏幕,所有视图的信息都来自JSON中的服务器,然后需要在屏幕上生成它们。 例如 - 应用程序从服务器获取json。这个json描述了必须构建的屏幕:

{
    "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
        }
    }]
}

所以,通过JSON,我需要在React Native中动态构建视图。但我看不到任何在JSX中编写JS代码的能力 - 只有静态视图和动态更改道具

4 个答案:

答案 0 :(得分:11)

是的,这是可能的。假设您成功检索JSON数据并将其保存到某个状态,然后在您的渲染功能中,您可以像这样使用它;

//  ViewControllerTwo.swift
import UIKit
import MapKit

class ViewControllerTwo: UIViewController {

    var latChosen : Double = 0.0;
    var longChosen : Double = 0.0;


    @IBOutlet var myMap: MKMapView!

    override func viewDidLoad() {
        super.viewDidLoad()
        myMap.mapType = MKMapType.satellite;
        let initialLocation = CLLocation(latitude: latChosen, longitude: longChosen);
        let regionRadius: CLLocationDistance = 1000;

        func centerMapOnLocation(location : CLLocation) {
            let coordinateRegion = MKCoordinateRegionMakeWithDistance(location.coordinate, regionRadius, regionRadius);
            myMap.setRegion(coordinateRegion, animated: true);
        }

        centerMapOnLocation(location: initialLocation);


    }



    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()

    }


    /*
    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        // Get the new view controller using segue.destinationViewController.
        // Pass the selected object to the new view controller.
    }
    */

}

我希望这段代码能给你一个想法。您可以根据自己的情况进行调整。

答案 1 :(得分:1)

这是另一种方法:-

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',
  },
});

您可以在 this Repo 上找到完整代码。

答案 2 :(得分:0)

是的,可以根据您从服务器检索的数据在React Native中动态创建组件。

但是,如果您希望应用程序检查最新的JS代码(包括新组件/视图)而无需通过应用商店进行更新,则可以使用类似代码的方法。 https://microsoft.github.io/code-push/

你的问题有点模糊,所以如果我误解了,那么你可以举例说明所有观点的信息。

答案 3 :(得分:0)

使用react native(vs。webview)的一个好处是,当应用程序加载数据时,您的用户不会盯着空屏幕。如果从服务器返回所有视图,那么它就像网页一样工作。我之前做过类似的事情。相信我,这不是最好的用户体验。理想情况下,json响应应该只返回数据。然后可以使用任何框架构建客户端(反应本机,iOS或Android本机),并且它们共享相同的API端点。