SDK35 managed app without ES6 class structure

  1. SDK Version: 35 / expo 3.4.1
  2. Platforms(Android/iOS/web/all): all
  3. Windows 10
  4. node v.12.13.0

When starting a new project expo init project-name and selecting blank (managed) the App.js component is structured as a function rather than a ES6 class which seems to be different to what is shown in expo snacks, docs and tutorials… how can I view the full ES6 class in managed app? I noticed if I use bare option it is class not function

App.js using SDK35 blank (managed):

export default function App() {
  return (
    <View style={styles.container}>
      <Text>Open up App.js to start working on your app!</Text>
    </View>
  );
}

Docs, Snacks, Tutorials:

export default class App extends React.component { 
    render() {  }
}

Is this a recent update relevant to SDK35 or am I missing something…?

It’s just another way of declaring a component. You can use class components or functional components (which is what App is in the example). They’re interchangeable. More information on functional components here: https://www.robinwieruch.de/react-function-component. With the introduction of hooks, functional components are becoming more popular, because they can now do things that only class components could do previously, like manage state, have lifecycle, etc. They probably switched App to a functional component because it is becoming the prevailing style.

You’re free to use all functional components, all class components, or a mixture of the two. You could switch App to be a class component if you’d like and it won’t hurt anything. A lot of us with a load of code already written will be going between the two formats for a very long time.

1 Like

The change conflicts with a bunch of code that they offer in their docs. For example I am trying to implement the AR API using the code from the docs and I copy / paste the code within the class into the new functional component and I get error when compiling, I get no error when in my text editor (Sublime) if I just use class. My code + error below:

Error:

Unexpected token, expected “;” (16:22)

** 14 | export default function App() {**

import React from 'react';
import { Platform, StyleSheet, Text, View } from 'react-native';
import { Button, ThemeProvider } from 'react-native-elements';

import { Asset } from 'expo-asset';
import { AR } from 'expo';
// Let's alias ExpoTHREE.AR as ThreeAR so it doesn't collide with Expo.AR.
import ExpoTHREE, { AR as ThreeAR, THREE } from 'expo-three';
// Let's also import `expo-graphics`
// expo-graphics manages the setup/teardown of the gl context/ar session, creates a frame-loop, and observes size/orientation changes.
// it also provides debug information with `isArCameraStateEnabled`
import { View as GraphicsView } from 'expo-graphics';

export default function App() {

  componentDidMount() {
    // Turn off extra warnings
    THREE.suppressExpoWarnings(true)
    ThreeAR.suppressWarnings()
  }
  
  render() {
    // You need to add the `isArEnabled` & `arTrackingConfiguration` props.
    // `isArRunningStateEnabled` Will show us the play/pause button in the corner.
    // `isArCameraStateEnabled` Will render the camera tracking information on the screen.
    // `arTrackingConfiguration` denotes which camera the AR Session will use. 
    // World for rear, Face for front (iPhone X only)
    return (
      <GraphicsView
        style={{ flex: 1 }}
        onContextCreate={this.onContextCreate}
        onRender={this.onRender}
        onResize={this.onResize}
        isArEnabled
        isArRunningStateEnabled
        isArCameraStateEnabled
        arTrackingConfiguration={'ARWorldTrackingConfiguration'}
      />
    );
  }

  // When our context is built we can start coding 3D things.
  onContextCreate = async ({ gl, scale: pixelRatio, width, height }) => {
    // This will allow ARKit to collect Horizontal surfaces
    AR.setPlaneDetection(AR.PlaneDetectionTypes.Horizontal);

    // Create a 3D renderer
    this.renderer = new ExpoTHREE.Renderer({
      gl,
      pixelRatio,
      width,
      height,
    });

    // We will add all of our meshes to this scene.
    this.scene = new THREE.Scene();
    // This will create a camera texture and use it as the background for our scene
    this.scene.background = new ThreeAR.BackgroundTexture(this.renderer);
    // Now we make a camera that matches the device orientation. 
    // Ex: When we look down this camera will rotate to look down too!
    this.camera = new ThreeAR.Camera(width, height, 0.01, 1000);
    
    // Make a cube - notice that each unit is 1 meter in real life, we will make our box 0.1 meters
    const geometry = new THREE.BoxGeometry(0.1, 0.1, 0.1);
    // Simple color material
    const material = new THREE.MeshPhongMaterial({
      color: 0xff00ff,
    });
    
    // Combine our geometry and material
    this.cube = new THREE.Mesh(geometry, material);
    // Place the box 0.4 meters in front of us.
    this.cube.position.z = -0.4
    // Add the cube to the scene
    this.scene.add(this.cube);
    
    // Setup a light so we can see the cube color
    // AmbientLight colors all things in the scene equally.
    this.scene.add(new THREE.AmbientLight(0xffffff));

    // Create this cool utility function that let's us see all the raw data points.
    this.points = new ThreeAR.Points();
    // Add the points to our scene...
    this.scene.add(this.points)
  };

  // When the phone rotates, or the view changes size, this method will be called.
  onResize = ({ x, y, scale, width, height }) => {
    // Let's stop the function if we haven't setup our scene yet
    if (!this.renderer) {
      return;
    }
    this.camera.aspect = width / height;
    this.camera.updateProjectionMatrix();
    this.renderer.setPixelRatio(scale);
    this.renderer.setSize(width, height);
  };

  // Called every frame.
  onRender = () => {
    // This will make the points get more rawDataPoints from Expo.AR
    this.points.update()
    // Finally render the scene with the AR Camera
    this.renderer.render(this.scene, this.camera);
  };
  
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

Hi

As @llamaluvr says your components can be class components or function components, but you can’t mix class methods into a function component.

So to fix your example, change this:

export default function App() {

to this:

export default class App extends React.Component {

Alternatively, change that line to e.g.:

class ARExample extends React.Component {

and add this above the const styles:

export default function App() {
  return (
    <ARExample />
  );
}

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.