hooks/useAccelerometer.ts

Purpose

The useAccelerometer hook provides a reactive interface to real-time accelerometer sensor data using react-native-sensors.

It is responsible for:

  • subscribing to device accelerometer updates
  • exposing live sensor values through React state
  • synchronizing sensor lifecycle with component lifecycle
  • configuring sensor sampling frequency
  • automatically cleaning up subscriptions on unmount

The hook is designed for lightweight motion-aware features in React Native applications.


Architecture Overview

The hook implements:

  • a single accelerometer subscription
  • React-managed sensor state
  • lifecycle-aware cleanup
  • fixed-rate sensor sampling

Sensor updates are streamed from:

accelerometer.subscribe(...)

and propagated through React state updates.


Invariants

The hook maintains the following invariants.


1. Accelerometer State Always Exists

The hook always returns a valid accelerometer object.

Initial state:

{
  x: 0,
  y: 0,
  z: 0,
  timestamp: Date.now()
}

This guarantees consumers never receive:

  • null
  • undefined
  • partially initialized sensor state

2. Exactly One Subscription Exists Per Hook Instance

The sensor subscription is created once inside:

useEffect(..., [])

The empty dependency array guarantees:

  • one subscription per mount
  • no duplicate subscriptions during re-renders

3. Subscriptions Are Always Cleaned Up

On component unmount:

sub.unsubscribe()

is always called.

This prevents:

  • memory leaks
  • orphaned sensor listeners
  • background sensor polling after unmount

4. Sampling Frequency Is Fixed

The hook configures the accelerometer update interval to:

1000 / 30

which corresponds to approximately:

30 Hz

This invariant ensures consistent sampling behavior across consumers.


5. Returned State Mirrors Latest Sensor Reading

Each accelerometer event fully replaces hook state:

setData({ x, y, z, timestamp })

The returned object always reflects the most recently received sensor sample.


Variants

Sensor Data Variants

The hook exposes four fields:

FieldTypeDescription
xnumberAcceleration along X-axis
ynumberAcceleration along Y-axis
znumberAcceleration along Z-axis
timestampnumberSensor event timestamp

Runtime Variants

Active Subscription State

While mounted:

  • accelerometer updates stream continuously
  • React state updates on every sensor event

Cleanup State

After unmount:

  • subscription is terminated
  • no additional sensor events are processed

Exported Functions

useAccelerometer()

export function useAccelerometer()

Subscribes to accelerometer updates and returns live sensor data.


Return Value

{
  x: number;
  y: number;
  z: number;
  timestamp: number;
}

Responsibilities

The hook:

  • initializes sensor state
  • configures accelerometer sampling interval
  • subscribes to accelerometer updates
  • propagates live readings through React state
  • cleans up subscriptions automatically

Sampling Configuration

The accelerometer interval is configured through:

setUpdateIntervalForType(
  SensorTypes.accelerometer,
  1000 / 30
)

Target frequency:

MetricValue
Frequency~30 Hz
Interval~33 ms

Example Usage

function MotionView() {
  const accel = useAccelerometer();

  return (
    <Text>
      X: {accel.x}
    </Text>
  );
}

Example Return Value

{
  x: -0.12,
  y: 0.98,
  z: 0.03,
  timestamp: 1716500000000
}

Internal Behavior

Subscription Flow

mount
  → configure sampling interval
  → subscribe to accelerometer
  → receive sensor updates
  → update React state

Cleanup Flow

unmount
  → unsubscribe sensor listener

Lifecycle Behavior

Mount

On component mount:

  1. accelerometer sampling interval is configured
  2. subscription is created
  3. sensor events begin streaming

Re-render

During re-renders:

  • subscription remains stable
  • no re-subscription occurs

because the effect dependency array is empty.


Unmount

On unmount:

sub.unsubscribe()

stops sensor updates immediately.


Sensor Configuration

Sensor Type

SensorTypes.accelerometer

Data Source

accelerometer.subscribe(...)

Sampling Interval

1000 / 30

Common Use Cases

The hook is suitable for:

  • activity recognition
  • motion visualization
  • gesture detection
  • movement tracking
  • orientation estimation
  • physics simulations
  • fitness telemetry
  • shake detection

Concurrency Notes

Each hook instance owns its own subscription.

Multiple mounted consumers will therefore create multiple subscriptions unless centralized elsewhere in the application architecture.


Performance Notes

At approximately 30 Hz:

  • updates occur every ~33 ms
  • React re-renders may occur frequently
  • consumers should avoid expensive render logic tied directly to sensor updates

For high-frequency processing pipelines, consider:

  • batching
  • throttling
  • memoization
  • centralized sensor streams

Example Integration

const accel = useAccelerometer();

if (accel.z > 1.2) {
  console.log("Device moved upward");
}