diff --git a/packages/sdk/react-native/README.md b/packages/sdk/react-native/README.md index da3d52acb..67a208ce0 100644 --- a/packages/sdk/react-native/README.md +++ b/packages/sdk/react-native/README.md @@ -1,6 +1,7 @@ # LaunchDarkly React Native SDK -:warning: UNSUPPORTED This SDK is in pre-release development and is not supported. +> [!WARNING] +> UNSUPPORTED This SDK is in pre-release development and is not supported. [![NPM][sdk-react-native-npm-badge]][sdk-react-native-npm-link] [![Actions Status][sdk-react-native-ci-badge]][sdk-react-native-ci] @@ -20,19 +21,80 @@ For more information, see the [complete reference guide for this SDK](https://do yarn add @launchdarkly/react-native-client-sdk ``` +Additionally, the LaunchDarkly React-Native SDK uses +[@react-native-async-storage/async-storage](https://github.com/react-native-async-storage/async-storage) +for bootstrapping. This is a native dependency. + +If you are using expo, then installing this package from npm like above and re-running pod install should suffice. + +If you are not using expo, you will need to explicitly add +@react-native-async-storage/async-storage as a dependency to your project +and re-run pod install for [auto-linking to work](https://github.com/react-native-community/cli/issues/1347). + ## Quickstart -TODO +1. Wrap your application with `LDProvider` passing it an LDClient and + an LDContext: + +```jsx +// App.tsx +import { LDProvider, ReactNativeLDClient } from '@launchdarkly/react-native-client-sdk'; + +const featureClient = new ReactNativeLDClient('mobile-key'); +const userContext = { kind: 'user', key: 'test-user-1' }; + +const App = () => ( + + + +); + +export default App; +``` + +2. Then in a child component, evaluate flags with `useBoolVariation`: + +```jsx +import { useBoolVariation } from '@launchdarkly/react-native-client-sdk'; + +export default function Welcome() { + const flagValue = useBoolVariation('flag-key', false); -```typescript -// TODO + return ( + + Welcome to LaunchDarkly + Flag value is {`${flagValue}`} + + ); +} ``` See the full [example app](https://github.com/launchdarkly/js-core/tree/main/packages/sdk/react-native/example). ## Developing this SDK -:information_source: See the example [README](https://github.com/launchdarkly/js-core/blob/main/packages/sdk/react-native/example/README.md#L1). +1. Build all the code in the `js-core` repo: + +```shell +# at js-core repo root +yarn && yarn build +``` + +2. The example app uses [react-native-dotenv](https://github.com/goatandsheep/react-native-dotenv) + to manage environment variables. Under `packages/sdk/react-native/example` + create an `.env` file and add your mobile key: + +```shell +echo "MOBILE_KEY=mob-abc" >> packages/sdk/react-native/example/.env +``` + +3. Run the example app. This will link the local react-native sdk code to the + example app for development: + +```shell +# in react-native/example +yarn && yarn ios-go +``` ## About LaunchDarkly diff --git a/packages/sdk/react-native/example/.gitignore b/packages/sdk/react-native/example/.gitignore index b252443a3..877c0f430 100644 --- a/packages/sdk/react-native/example/.gitignore +++ b/packages/sdk/react-native/example/.gitignore @@ -37,3 +37,5 @@ yarn-error.* ios android + +!yarn.lock diff --git a/packages/sdk/react-native/example/App.tsx b/packages/sdk/react-native/example/App.tsx index 56634e16e..0855d46a7 100644 --- a/packages/sdk/react-native/example/App.tsx +++ b/packages/sdk/react-native/example/App.tsx @@ -5,11 +5,10 @@ import { LDProvider, ReactNativeLDClient } from '@launchdarkly/react-native-clie import Welcome from './src/welcome'; const featureClient = new ReactNativeLDClient(MOBILE_KEY); -const context = { kind: 'user', key: 'test-user-1' }; const App = () => { return ( - + ); diff --git a/packages/sdk/react-native/example/README.md b/packages/sdk/react-native/example/README.md index 2307d41b9..8cc13d9f9 100644 --- a/packages/sdk/react-native/example/README.md +++ b/packages/sdk/react-native/example/README.md @@ -20,11 +20,11 @@ MOBILE_KEY=abcdef12456 ```shell # Note for android, there's an issue with Flipper interfering with streaming connections -# so please run the release build. There's no such issue with ios. - -# android -yarn && yarn android-release +# so please run the release build. There's no such issues with ios. # ios yarn && yarn ios-go + +# android +yarn && yarn android-release ``` diff --git a/packages/sdk/react-native/example/package.json b/packages/sdk/react-native/example/package.json index 113904380..7901a2457 100644 --- a/packages/sdk/react-native/example/package.json +++ b/packages/sdk/react-native/example/package.json @@ -5,16 +5,18 @@ "scripts": { "start": "expo start", "expo-clean": "expo prebuild --clean", - "android": "expo run:android", - "android-release": "expo run:android --variant release", - "android-go": "expo start --android --clear", + "android": "yarn link-dev && expo run:android", + "android-release": "yarn link-dev && expo run:android --variant release", + "android-go": "yarn link-dev && expo start --android --clear", "android-log": "react-native log-android", - "ios": "expo run:ios", - "ios-release": "expo run:ios --configuration Release", - "ios-go": "expo start --ios --clear", + "ios": "yarn link-dev && expo run:ios", + "ios-release": "yarn link-dev && expo run:ios --configuration Release", + "ios-go": "yarn link-dev && expo start --ios --clear", "ios-log": "react-native log-ios", - "web": "expo start --web --clear", - "clean": "expo prebuild --clean && yarn cache clean && rm -rf node_modules && rm -rf .expo" + "web": "yarn link-dev && expo start --web --clear", + "clean": "expo prebuild --clean && yarn cache clean && rm -rf node_modules && rm -rf .expo", + "link-dev": "(cd .. && yarn build)", + "postinstall": "yarn link-dev" }, "dependencies": { "expo": "~49.0.16", diff --git a/packages/sdk/react-native/example/src/welcome.tsx b/packages/sdk/react-native/example/src/welcome.tsx index dd42ebbf6..54ec0333b 100644 --- a/packages/sdk/react-native/example/src/welcome.tsx +++ b/packages/sdk/react-native/example/src/welcome.tsx @@ -1,28 +1,46 @@ -import { Button, StyleSheet, Text, View } from 'react-native'; +import { useState } from 'react'; +import { StyleSheet, Text, TextInput, TouchableOpacity, View } from 'react-native'; -import { - useBoolVariation, - useLDClient, - useLDDataSourceStatus, -} from '@launchdarkly/react-native-client-sdk'; +import { useBoolVariation, useLDClient } from '@launchdarkly/react-native-client-sdk'; export default function Welcome() { - const { error, status } = useLDDataSourceStatus(); - const flag = useBoolVariation('dev-test-flag', false); + const [flagKey, setFlagKey] = useState('dev-test-flag'); + const [userKey, setUserKey] = useState(''); + const flagValue = useBoolVariation(flagKey, false); const ldc = useLDClient(); - const login = () => { - ldc.identify({ kind: 'user', key: 'test-user-2' }); + const onIdentify = () => { + ldc + .identify({ kind: 'user', key: userKey }) + .catch((e: any) => console.error(`error identifying ${userKey}: ${e}`)); }; return ( Welcome to LaunchDarkly - status: {status ?? 'not connected'} - {error ? error: {error.message} : null} - devTestFlag: {`${flag}`} + + {flagKey}: {`${flagValue}`} + context: {JSON.stringify(ldc.getContext())} -