Skip to content

Commit 37ff40e

Browse files
authored
chore: rn sdk use localstorage for bootstrapping (#326)
Please run the example app as well if you can by running `yarn ios` from the `react-native` folder. Note that [expo 49 only supports rn 0.72](https://docs.expo.dev/versions/latest/#each-expo-sdk-version-depends-on-a-react-native-version). Expo 50 will work with 0.73 and it's in beta with full release coming in about month. Thank you for reviewing. * Added bootstrap from storage. * Added local copy of fast-deep-equal (see my comments [here](https://github.com/launchdarkly/js-core/pull/326/files#r1430690374)). * Cleaned up and improved React Native SDK api and example.
1 parent 78aac46 commit 37ff40e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+10308
-408
lines changed

packages/sdk/react-native/README.md

Lines changed: 67 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# LaunchDarkly React Native SDK
22

3-
:warning: UNSUPPORTED This SDK is in pre-release development and is not supported.
3+
> [!WARNING]
4+
> UNSUPPORTED This SDK is in pre-release development and is not supported.
45
56
[![NPM][sdk-react-native-npm-badge]][sdk-react-native-npm-link]
67
[![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
2021
yarn add @launchdarkly/react-native-client-sdk
2122
```
2223

24+
Additionally, the LaunchDarkly React-Native SDK uses
25+
[@react-native-async-storage/async-storage](https://github.com/react-native-async-storage/async-storage)
26+
for bootstrapping. This is a native dependency.
27+
28+
If you are using expo, then installing this package from npm like above and re-running pod install should suffice.
29+
30+
If you are not using expo, you will need to explicitly add
31+
@react-native-async-storage/async-storage as a dependency to your project
32+
and re-run pod install for [auto-linking to work](https://github.com/react-native-community/cli/issues/1347).
33+
2334
## Quickstart
2435

25-
TODO
36+
1. Wrap your application with `LDProvider` passing it an LDClient and
37+
an LDContext:
38+
39+
```jsx
40+
// App.tsx
41+
import { LDProvider, ReactNativeLDClient } from '@launchdarkly/react-native-client-sdk';
42+
43+
const featureClient = new ReactNativeLDClient('mobile-key');
44+
const userContext = { kind: 'user', key: 'test-user-1' };
45+
46+
const App = () => (
47+
<LDProvider client={featureClient} context={userContext}>
48+
<Welcome />
49+
</LDProvider>
50+
);
51+
52+
export default App;
53+
```
54+
55+
2. Then in a child component, evaluate flags with `useBoolVariation`:
56+
57+
```jsx
58+
import { useBoolVariation } from '@launchdarkly/react-native-client-sdk';
59+
60+
export default function Welcome() {
61+
const flagValue = useBoolVariation('flag-key', false);
2662

27-
```typescript
28-
// TODO
63+
return (
64+
<View style={styles.container}>
65+
<Text>Welcome to LaunchDarkly</Text>
66+
<Text>Flag value is {`${flagValue}`}</Text>
67+
</View>
68+
);
69+
}
2970
```
3071

3172
See the full [example app](https://github.com/launchdarkly/js-core/tree/main/packages/sdk/react-native/example).
3273

3374
## Developing this SDK
3475

35-
:information_source: See the example [README](https://github.com/launchdarkly/js-core/blob/main/packages/sdk/react-native/example/README.md#L1).
76+
1. Build all the code in the `js-core` repo:
77+
78+
```shell
79+
# at js-core repo root
80+
yarn && yarn build
81+
```
82+
83+
2. The example app uses [react-native-dotenv](https://github.com/goatandsheep/react-native-dotenv)
84+
to manage environment variables. Under `packages/sdk/react-native/example`
85+
create an `.env` file and add your mobile key:
86+
87+
```shell
88+
echo "MOBILE_KEY=mob-abc" >> packages/sdk/react-native/example/.env
89+
```
90+
91+
3. Run the example app. This will link the local react-native sdk code to the
92+
example app for development:
93+
94+
```shell
95+
# in react-native/example
96+
yarn && yarn ios-go
97+
```
3698

3799
## About LaunchDarkly
38100

packages/sdk/react-native/example/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,5 @@ yarn-error.*
3737

3838
ios
3939
android
40+
41+
!yarn.lock

packages/sdk/react-native/example/App.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,10 @@ import { LDProvider, ReactNativeLDClient } from '@launchdarkly/react-native-clie
55
import Welcome from './src/welcome';
66

77
const featureClient = new ReactNativeLDClient(MOBILE_KEY);
8-
const context = { kind: 'user', key: 'test-user-1' };
98

109
const App = () => {
1110
return (
12-
<LDProvider client={featureClient} context={context}>
11+
<LDProvider client={featureClient}>
1312
<Welcome />
1413
</LDProvider>
1514
);

packages/sdk/react-native/example/README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,11 @@ MOBILE_KEY=abcdef12456
2020

2121
```shell
2222
# Note for android, there's an issue with Flipper interfering with streaming connections
23-
# so please run the release build. There's no such issue with ios.
24-
25-
# android
26-
yarn && yarn android-release
23+
# so please run the release build. There's no such issues with ios.
2724

2825
# ios
2926
yarn && yarn ios-go
27+
28+
# android
29+
yarn && yarn android-release
3030
```

packages/sdk/react-native/example/package.json

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,18 @@
55
"scripts": {
66
"start": "expo start",
77
"expo-clean": "expo prebuild --clean",
8-
"android": "expo run:android",
9-
"android-release": "expo run:android --variant release",
10-
"android-go": "expo start --android --clear",
8+
"android": "yarn link-dev && expo run:android",
9+
"android-release": "yarn link-dev && expo run:android --variant release",
10+
"android-go": "yarn link-dev && expo start --android --clear",
1111
"android-log": "react-native log-android",
12-
"ios": "expo run:ios",
13-
"ios-release": "expo run:ios --configuration Release",
14-
"ios-go": "expo start --ios --clear",
12+
"ios": "yarn link-dev && expo run:ios",
13+
"ios-release": "yarn link-dev && expo run:ios --configuration Release",
14+
"ios-go": "yarn link-dev && expo start --ios --clear",
1515
"ios-log": "react-native log-ios",
16-
"web": "expo start --web --clear",
17-
"clean": "expo prebuild --clean && yarn cache clean && rm -rf node_modules && rm -rf .expo"
16+
"web": "yarn link-dev && expo start --web --clear",
17+
"clean": "expo prebuild --clean && yarn cache clean && rm -rf node_modules && rm -rf .expo",
18+
"link-dev": "(cd .. && yarn build)",
19+
"postinstall": "yarn link-dev"
1820
},
1921
"dependencies": {
2022
"expo": "~49.0.16",
Lines changed: 52 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,46 @@
1-
import { Button, StyleSheet, Text, View } from 'react-native';
1+
import { useState } from 'react';
2+
import { StyleSheet, Text, TextInput, TouchableOpacity, View } from 'react-native';
23

3-
import {
4-
useBoolVariation,
5-
useLDClient,
6-
useLDDataSourceStatus,
7-
} from '@launchdarkly/react-native-client-sdk';
4+
import { useBoolVariation, useLDClient } from '@launchdarkly/react-native-client-sdk';
85

96
export default function Welcome() {
10-
const { error, status } = useLDDataSourceStatus();
11-
const flag = useBoolVariation('dev-test-flag', false);
7+
const [flagKey, setFlagKey] = useState('dev-test-flag');
8+
const [userKey, setUserKey] = useState('');
9+
const flagValue = useBoolVariation(flagKey, false);
1210
const ldc = useLDClient();
1311

14-
const login = () => {
15-
ldc.identify({ kind: 'user', key: 'test-user-2' });
12+
const onIdentify = () => {
13+
ldc
14+
.identify({ kind: 'user', key: userKey })
15+
.catch((e: any) => console.error(`error identifying ${userKey}: ${e}`));
1616
};
1717

1818
return (
1919
<View style={styles.container}>
2020
<Text>Welcome to LaunchDarkly</Text>
21-
<Text>status: {status ?? 'not connected'}</Text>
22-
{error ? <Text>error: {error.message}</Text> : null}
23-
<Text>devTestFlag: {`${flag}`}</Text>
21+
<Text>
22+
{flagKey}: {`${flagValue}`}
23+
</Text>
2424
<Text>context: {JSON.stringify(ldc.getContext())}</Text>
25-
<Button title="Login" onPress={login} />
25+
<TextInput
26+
style={styles.input}
27+
autoCapitalize="none"
28+
onChangeText={setUserKey}
29+
onSubmitEditing={onIdentify}
30+
value={userKey}
31+
/>
32+
<TouchableOpacity onPress={onIdentify} style={styles.buttonContainer}>
33+
<Text style={styles.buttonText}>identify</Text>
34+
</TouchableOpacity>
35+
<TextInput
36+
style={styles.input}
37+
autoCapitalize="none"
38+
onChangeText={setFlagKey}
39+
value={flagKey}
40+
/>
41+
<TouchableOpacity style={styles.buttonContainer}>
42+
<Text style={styles.buttonText}>get flag value</Text>
43+
</TouchableOpacity>
2644
</View>
2745
);
2846
}
@@ -33,9 +51,25 @@ const styles = StyleSheet.create({
3351
alignItems: 'center',
3452
justifyContent: 'center',
3553
},
36-
box: {
37-
width: 60,
38-
height: 60,
39-
marginVertical: 20,
54+
input: {
55+
height: 40,
56+
margin: 12,
57+
borderWidth: 1,
58+
padding: 10,
59+
},
60+
buttonContainer: {
61+
elevation: 8,
62+
backgroundColor: '#009688',
63+
borderRadius: 10,
64+
paddingVertical: 10,
65+
paddingHorizontal: 12,
66+
marginBottom: 20,
67+
},
68+
buttonText: {
69+
fontSize: 18,
70+
color: '#fff',
71+
fontWeight: 'bold',
72+
alignSelf: 'center',
73+
textTransform: 'uppercase',
4074
},
4175
});

0 commit comments

Comments
 (0)