React Native Expo中使用react-native-shake监听摇一摇事件报错求助
Hey there! Let’s break down why your shake detection code is throwing errors and how to fix it properly.
The Core Issue
The react-native-shake package you’re using is a native module that requires direct access to iOS/Android native code. Unfortunately, this package isn’t compatible with Expo’s Managed Workflow (the default setup when you use Expo CLI), since Managed Workflow restricts direct modifications to native project files. That’s almost certainly why you’re seeing errors.
Solution 1: Use Expo’s Official expo-sensors (Recommended)
Expo provides a built-in library called expo-sensors that includes an Accelerometer API—perfect for detecting shake events without any native setup. Here’s how to implement it:
Step 1: Install the dependency
npx expo install expo-sensors
Step 2: Replace your component with this code
This example uses the accelerometer to track movement and detect shakes by measuring sudden changes in acceleration:
import React, { Component } from 'react'; import { View, Text } from 'react-native'; import { Accelerometer } from 'expo-sensors'; export class Shaker extends Component { _subscription = null; componentDidMount() { this.startShakeDetection(); } componentWillUnmount() { this.stopShakeDetection(); } startShakeDetection = () => { let lastAcceleration = { x: 0, y: 0, z: 0 }; // Adjust this threshold based on how sensitive you want the shake to be const shakeThreshold = 14; this._subscription = Accelerometer.addListener(accelerometerData => { const { x, y, z } = accelerometerData; // Calculate the difference between current and last acceleration values const deltaX = Math.abs(x - lastAcceleration.x); const deltaY = Math.abs(y - lastAcceleration.y); const deltaZ = Math.abs(z - lastAcceleration.z); // Trigger shake event if any axis exceeds the threshold if (deltaX > shakeThreshold || deltaY > shakeThreshold || deltaZ > shakeThreshold) { console.log("Shaked!"); // Add your custom shake logic here } lastAcceleration = { x, y, z }; }); // Set how often the accelerometer updates (in milliseconds) Accelerometer.setUpdateInterval(100); }; stopShakeDetection = () => { if (this._subscription) { this._subscription.remove(); this._subscription = null; } }; render() { return ( <View> <Text>Shake your Phone</Text> </View> ); } } export default Shaker;
Solution 2: Switch to Expo Bare Workflow (If You Must Use react-native-shake)
If you really want to stick with react-native-shake, you’ll need to switch to Expo’s Bare Workflow, which lets you modify native code. Here’s how:
- Generate native project files:
npx expo prebuild - Reinstall and link the package:
npm install react-native-shake # For iOS, install pods: npx pod-install - Rebuild your app and test the shake detection again.
Quick Note on Your Original Code
Also, don’t forget to import React and Component at the top of your file—your original code was missing this line, which would cause an additional error:
import React, { Component } from 'react';
内容的提问来源于stack exchange,提问作者jony-jas

