Home > Enterprise >  How do I wrap React-Native Alert so it will use the colorScheme from a context?
How do I wrap React-Native Alert so it will use the colorScheme from a context?

Time:12-31

Similar to Access React Context outside of render function but I am looking to add a way of extending Alert.alert so that it will use the color scheme from theme.

  const { colorScheme } = useTheming();
...
    Alert.alert(t`logout`, "Are you sure you want to logout?", [
      {
        text: "No",
      },
      {
        style: "destructive",
        text: "Yes",
        onPress: logoutAsync,
      },
    ], {
      userInterfaceStyle: colorScheme
    });

I just want it so that the color scheme does not need to be added in.

I started with

import { Alert as RNAlert } from 'react-native'
export class Alert implements RNAlert {
  static alert(...) {
     // how do I get the data from the context?
  }
  static prompt(...) {
  }
}

CodePudding user response:

This isn't a proper answer yet since I don't wrap the Alert object, but this is the closest I have gotten.

import { useCallback } from 'react';
import { Alert as RNAlert, AlertButton, AlertOptions } from 'react-native';
import { useTheming } from "./ThemeContext";

export function useAlert(): RNAlert {
    const { colorScheme } = useTheming();
    const alert = useCallback((title: string, message?: string, buttons?: AlertButton[], options?: AlertOptions): void => {
        const newOptions = { userInterfaceStyle: options?.userInterfaceStyle ?? colorScheme, ...options }
        RNAlert.alert(title, message, buttons, newOptions);
    }, [colorScheme])
    return { alert, prompt: RNAlert.prompt };
}

The key thing to watch out for is when you're using it with useCallback you have to remember to add the new alert to the dependency list.

  const { alert } = useAlert();
  ...
  const handleLogout = useCallback(() => {
    alert(t`logout`, "Are you sure you want to logout?", [
      {
        text: "No",
      },
      {
        text: "Yes",
        onPress: logoutAsync,
      },
    ]);
  }, [logoutAsync, alert]);

CodePudding user response:

1. First, make sure that you have a context that provides the color scheme. For example, you could create a ThemeContext that provides the current theme (e.g., light or dark).

2. Next, create a custom component that wraps the Alert component and retrieves the color scheme from the context. You can do this by using the useContext hook to get the color scheme from the context and pass it as a prop to the Alert component. Here's an example of what this component might look like:

    import { useContext } from 'react';
import { Alert } from 'react-native';
import { ThemeContext } from './ThemeContext';

function ThemedAlert(props) {
  const { colorScheme } = useContext(ThemeContext);
  return <Alert {...props} colorScheme={colorScheme} />;
}

3. Finally, use the ThemedAlert component wherever you want to show an alert with the color scheme from the context. Here's an example of how you might use the ThemedAlert component: import ThemedAlert from './ThemedAlert';

function MyComponent() {
  return (
    <ThemedAlert
      title="My Alert"
      message="This is an alert with a themed color scheme."
      onPress={() => console.log('Button pressed')}
    />
  );
}

I hope this helps! Let me know if you have any questions.

  • Related