0Pricing
React Native Academy · บทเรียน

การจัดการสิทธิ์อย่างเหมาะสม

ตรวจสอบสถานะสิทธิ์ก่อนขอ แสดงคำอธิบายตามบริบทแก่ผู้ใช้ และลดความสามารถของฟีเจอร์ลงอย่างเหมาะสมเมื่อไม่ได้รับสิทธิ์

การจัดการสิทธิ์อย่างเหมาะสม เป็นบทเรียน React Native Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน React Native Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส React Native Academy มีบทเรียนทั้งหมด 4 บทเรียน

บางส่วนของบทเรียนนี้ยังไม่ได้รับการแปล และแสดงเป็นภาษาอังกฤษ

Why Permission Handling Matters

iOS and Android require explicit user consent before an app can access sensitive capabilities like the camera, location, microphone, or contacts. How you ask for and respond to permission decisions significantly affects user trust and app ratings. A poorly timed or unexplained permission request often results in denial, and once denied, the only recovery path is the device's Settings app.

Permission Lifecycle: The Four States

A permission can be in one of four states: undetermined (never asked yet), granted (user allowed it), denied (user said no during the last prompt), and restricted (iOS — blocked by parental controls, cannot be changed). Your app must handle each state correctly and never assume a permission is granted without checking.

import { PermissionStatus } from 'expo-location';

const { status } = await Location.getForegroundPermissionsAsync();

switch (status) {
  case PermissionStatus.UNDETERMINED:
    // Safe to call requestForegroundPermissionsAsync()
    break;
  case PermissionStatus.GRANTED:
    // Proceed with the feature
    break;
  case PermissionStatus.DENIED:
    // Show instructions to open Settings
    break;
}

Check Before Requesting

Always check the current permission status with a get*Async call before calling request*Async. If the permission is already granted, skip the request dialog. If it was already denied, do not re-prompt — iOS will silently ignore the request and Android will briefly flash a snackbar. Only prompt when status is undetermined.

async function ensureCameraPermission(): Promise<boolean> {
  const { status } = await Camera.getCameraPermissionsAsync();

  if (status === 'granted') return true;

  if (status === 'undetermined') {
    const { status: newStatus } = await Camera.requestCameraPermissionsAsync();
    return newStatus === 'granted';
  }

  // status === 'denied' — direct user to Settings
  return false;
}

Contextual Pre-Permission Rationale

Before triggering the OS permission dialog, show the user a custom rationale screen that explains in plain language why your app needs the permission and how it benefits them. This 'prime' screen dramatically increases grant rates. It should appear right before the system dialog, not during onboarding before any feature context is established.

function LocationRationale({ onConfirm }: { onConfirm: () => void }) {
  return (
    <View style={styles.rationale}>
      <Ionicons name='location-outline' size={48} color='#6200ee' />
      <Text style={styles.title}>Share your location</Text>
      <Text style={styles.body}>
        We use your location to show nearby restaurants and
        calculate accurate delivery times.
      </Text>
      <Button title='Allow Location' onPress={onConfirm} />
      <Button title='Not Now' onPress={() => {}} color='gray' />
    </View>
  );
}

Linking to App Settings When Denied

When a user has denied a permission and the feature cannot work without it, guide them to the device Settings app to manually grant it. Use Linking.openSettings() from React Native to open the app's settings page directly. Explain in an alert what they need to enable before calling openSettings.

import { Linking, Alert } from 'react-native';

function showSettingsPrompt(feature: string) {
  Alert.alert(
    feature + ' Access Denied',
    'Please enable ' + feature + ' access in your device Settings to use this feature.',
    [
      { text: 'Cancel', style: 'cancel' },
      { text: 'Open Settings', onPress: () => Linking.openSettings() },
    ]
  );
}

Graceful Degradation

Graceful degradation means your app still works — with reduced functionality — when a permission is denied. For example, a food delivery app denied location access can show a manual address input instead of auto-detecting the address. Design every permission-gated feature with a fallback path so no user is completely blocked from the app's core value.

export default function LocationPicker() {
  const [permission] = Location.useForegroundPermissions();
  const granted = permission?.granted;

  if (granted) {
    return <MapWithAutoLocation />; // use GPS
  }

  return <ManualAddressInput />;   // fallback — type address manually
}

canAskAgain: One Chance to Re-Request

The permission result object includes a canAskAgain property. On iOS, once the user taps 'Don't Allow' on the system dialog, canAskAgain becomes false and the system will never show the dialog again for that permission. On Android, it becomes false after the user denies twice. Always check this flag to decide whether to show the re-prompt button or the Settings link.

const { status, canAskAgain } = await Camera.requestCameraPermissionsAsync();

if (status !== 'granted') {
  if (canAskAgain) {
    // Show in-app explanation and re-request button
    setShowRationale(true);
  } else {
    // Show link to Settings — OS won't show dialog again
    showSettingsPrompt('Camera');
  }
}

Handling Multiple Permissions

Some features require multiple permissions simultaneously — for example a media picker needs both camera and media library access. Request them in sequence, checking each result before requesting the next. If any permission is denied, handle it and stop — do not proceed to the next request so users are not overwhelmed by multiple system dialogs in rapid succession.

async function requestMediaFeaturePermissions() {
  const { status: cameraStatus } = await Camera.requestCameraPermissionsAsync();
  if (cameraStatus !== 'granted') {
    showSettingsPrompt('Camera');
    return false;
  }
  const { status: mediaStatus } = await MediaLibrary.requestPermissionsAsync();
  if (mediaStatus !== 'granted') {
    showSettingsPrompt('Media Library');
    return false;
  }
  return true;
}

Persisting Permission State

You do not need to persist permission state in AsyncStorage — always query it fresh with get*Async calls because the user can change permissions in device Settings between app sessions. However, you can persist a flag like hasSeenPermissionRationale in AsyncStorage so you only show your custom rationale screen once and do not re-show it on every app launch.

async function maybeShowRationale() {
  const seen = await AsyncStorage.getItem('seenLocationRationale');
  if (!seen) {
    setShowRationale(true);
    await AsyncStorage.setItem('seenLocationRationale', 'true');
  } else {
    // Rationale seen before — go straight to checking permission
    await checkLocationPermission();
  }
}

Testing Permission Flows

Test all four permission states: first launch (undetermined), granted, denied, and denied with canAskAgain=false. On iOS Simulator, reset permissions via Device Settings app. On Android Emulator, use App Info to revoke permissions manually. Also test the Settings link — make sure it opens the correct per-app settings page, not the general device settings screen.

A Reusable Permission Hook

Encapsulate the full permission lifecycle — check, rationale, request, and Settings fallback — into a reusable custom hook. The hook returns the current status and a function to trigger the permission request. This eliminates duplicated permission handling code across multiple screens that need the same capability.

function useCameraPermission() {
  const [status, setStatus] = React.useState<string>('undetermined');

  async function request() {
    const { status: s, canAskAgain } = await Camera.requestCameraPermissionsAsync();
    setStatus(s);
    if (s !== 'granted' && !canAskAgain) {
      showSettingsPrompt('Camera');
    }
  }

  useEffect(() => {
    Camera.getCameraPermissionsAsync().then(({ status: s }) => setStatus(s));
  }, []);

  return { status, granted: status === 'granted', request };
}

Quick Check

Test your understanding of React Native Mobile Development concepts from this lesson.

Lesson Recap

In this lesson you learned: checking permission status before requesting prevents redundant system dialogs and handles already-denied states correctly, canAskAgain determines whether to re-prompt or direct users to Settings, and graceful degradation provides a fallback path so denied permissions don't completely block users from your app. Next up we explore forms and validation with react-hook-form.

คำถามที่พบบ่อย

บทเรียน “การจัดการสิทธิ์อย่างเหมาะสม” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “การจัดการสิทธิ์อย่างเหมาะสม” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส React Native Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส React Native Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “การจัดการสิทธิ์อย่างเหมาะสม”

ตรวจสอบสถานะสิทธิ์ก่อนขอ แสดงคำอธิบายตามบริบทแก่ผู้ใช้ และลดความสามารถของฟีเจอร์ลงอย่างเหมาะสมเมื่อไม่ได้รับสิทธิ์ คุณปฏิบัติ React Native Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน React Native Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน React Native Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน

บทเรียน “การจัดการสิทธิ์อย่างเหมาะสม” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน React Native Academy นี้ได้ไหม

ได้ บทเรียน React Native Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. การเข้าถึงกล้องด้วย expo-camera
  2. การอ่านตำแหน่ง GPS ด้วย expo-location
  3. การตั้งเวลาการแจ้งเตือนภายในเครื่อง
  4. การจัดการสิทธิ์อย่างเหมาะสม
← กลับไปที่ React Native Academy