Skip to content

Commit

Permalink
fix: Add all docs back that were accidentally deleted
Browse files Browse the repository at this point in the history
  • Loading branch information
mrousavy committed Apr 30, 2024
1 parent ad004a6 commit a3c096e
Show file tree
Hide file tree
Showing 8 changed files with 355 additions and 0 deletions.
85 changes: 85 additions & 0 deletions docs/HOOKS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# Hooks

react-native-mmkv provides an easy to use React-Hooks API to be used in Function Components.

## Reactively use individual keys

```tsx
function App() {
const [username, setUsername] = useMMKVString("user.name")
const [age, setAge] = useMMKVNumber("user.age")
const [isPremiumUser, setIsPremiumUser] = useMMKVBoolean("user.isPremium")
const [privateKey, setPrivateKey] = useMMKVBuffer("user.privateKey")
}
```

## Clear a key

```tsx
function App() {
const [username, setUsername] = useMMKVString("user.name")
// ...
const onLogout = useCallback(() => {
setUsername(undefined)
}, [])
}
```

## Objects

```tsx
type User = {
id: string
username: string
age: number
}

function App() {
const [user, setUser] = useMMKVObject<User>("user")
}
```

## Reactively use an MMKV Instance

```tsx
function App() {
const storage = useMMKV()
// ...
const onLogin = useCallback((username) => {
storage.set("user.name", "Marc")
}, [storage])
}
```

## Reactively use individual keys from custom instances

```tsx
function App() {
const globalStorage = useMMKV()
const userStorage = useMMKV({ id: `${userId}.storage` })

const [username, setUsername] = useMMKVString("user.name", userStorage)
}
```

## Listen to value changes

```tsx
function App() {
useMMKVListener((key) => {
console.log(`Value for "${key}" changed!`)
})
}
```

## Listen to value changes on a specific instance

```tsx
function App() {
const storage = useMMKV({ id: `${userId}.storage` })

useMMKVListener((key) => {
console.log(`Value for "${key}" changed in user storage!`)
}, storage)
}
```
29 changes: 29 additions & 0 deletions docs/LISTENERS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Listeners

MMKV instances also contain an observer/listener registry.

### Add a listener when a `key`'s `value` changes.

```ts
const storage = new MMKV()

const listener = storage.addOnValueChangedListener((changedKey) => {
const newValue = storage.getString(changedKey)
console.log(`"${changedKey}" new value: ${newValue}`)
})
```

Don't forget to remove the listener when no longer needed. For example, when the user logs out:

```ts
function SettingsScreen() {
// ...

const onLogout = useCallback(() => {
// ...
listener.remove()
}, [])

// ...
}
```
114 changes: 114 additions & 0 deletions docs/MIGRATE_FROM_ASYNC_STORAGE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
# Migrate from AsyncStorage

Here's a migration script to copy all values from AsyncStorage to MMKV, and delete them from AsyncStorage afterwards.

<table>
<tr>
<th><code>storage.ts</code></th>
</tr>
<tr>
<td>

```ts
import AsyncStorage from '@react-native-async-storage/async-storage';
import {MMKV} from 'react-native-mmkv';

export const storage = new MMKV();

// TODO: Remove `hasMigratedFromAsyncStorage` after a while (when everyone has migrated)
export const hasMigratedFromAsyncStorage = storage.getBoolean(
'hasMigratedFromAsyncStorage',
);

// TODO: Remove `hasMigratedFromAsyncStorage` after a while (when everyone has migrated)
export async function migrateFromAsyncStorage(): Promise<void> {
console.log('Migrating from AsyncStorage -> MMKV...');
const start = global.performance.now();

const keys = await AsyncStorage.getAllKeys();

for (const key of keys) {
try {
const value = await AsyncStorage.getItem(key);

if (value != null) {
if (['true', 'false'].includes(value)) {
storage.set(key, value === 'true');
} else {
storage.set(key, value);
}

AsyncStorage.removeItem(key);
}
} catch (error) {
console.error(
`Failed to migrate key "${key}" from AsyncStorage to MMKV!`,
error,
);
throw error;
}
}

storage.set('hasMigratedFromAsyncStorage', true);

const end = global.performance.now();
console.log(`Migrated from AsyncStorage -> MMKV in ${end - start}ms!`);
}
```

</td>
</tr>
</table>




<table>
<tr>
<th><code>App.tsx</code></th>
</tr>
<tr>
<td>

```tsx
...
import { hasMigratedFromAsyncStorage, migrateFromAsyncStorage } from './storage';
...

export default function App() {
// TODO: Remove `hasMigratedFromAsyncStorage` after a while (when everyone has migrated)
const [hasMigrated, setHasMigrated] = useState(hasMigratedFromAsyncStorage);

...

useEffect(() => {
if (!hasMigratedFromAsyncStorage) {
InteractionManager.runAfterInteractions(async () => {
try {
await migrateFromAsyncStorage()
setHasMigrated(true)
} catch (e) {
// TODO: fall back to AsyncStorage? Wipe storage clean and use MMKV? Crash app?
}
});
}
}, []);

if (!hasMigrated) {
// show loading indicator while app is migrating storage...
return (
<View style={{ justifyContent: 'center', alignItems: 'center' }}>
<ActivityIndicator color="black" />
</View>
);
}

return (
<YourAppsCode />
);
}
```

</td>
</tr>
</table>
18 changes: 18 additions & 0 deletions docs/WRAPPER_MOBX.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# mobx-persist-store wrapper

If you want to use MMKV with [mobx-persist-store](https://github.com/quarrant/mobx-persist-store), create the following `storage` object:

```ts
import { configurePersistable } from 'mobx-persist-store'
import { MMKV } from "react-native-mmkv"

const storage = new MMKV()

configurePersistable({
storage: {
setItem: (key, data) => storage.set(key, data),
getItem: (key) => storage.getString(key),
removeItem: (key) => storage.delete(key),
},
})
```
37 changes: 37 additions & 0 deletions docs/WRAPPER_MOBXPERSIST.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# mobx-persist wrapper

If you want to use MMKV with [mobx-persist](https://github.com/pinqy520/mobx-persist), create the following `hydrate` function:

```ts
import { create } from "mobx-persist"
import { MMKV } from "react-native-mmkv"

const storage = new MMKV()

const mmkvStorage = {
clear: () => {
storage.clearAll()
return Promise.resolve()
},
setItem: (key, value) => {
storage.set(key, value)
return Promise.resolve(true)
},
getItem: (key) => {
const value = storage.getString(key)
return Promise.resolve(value)
},
removeItem: (key) => {
storage.delete(key)
return Promise.resolve()
},
}

const hydrate = create({
storage: mmkvStorage,
jsonify: true,
})

```

You can see a full working example [here](https://github.com/riamon-v/rn-mmkv-with-mobxpersist)
24 changes: 24 additions & 0 deletions docs/WRAPPER_RECOIL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# recoil storage wrapper

If you want to use MMKV with [recoil](https://recoiljs.org/), Use the following persist code:

```tsx
const persistAtom = (key) => ({ setSelf, onSet }) => {
setSelf(() => {
let data = storage.getString(key);
if (data != null){
return JSON.parse(data);
} else {
return new DefaultValue();
}
});

onSet((newValue, _, isReset) => {
if (isReset) {
storage.delete(key);
} else {
storage.set(key, JSON.stringify(newValue));
}
});
};
```
25 changes: 25 additions & 0 deletions docs/WRAPPER_REDUX.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# redux-persist storage wrapper

If you want to use MMKV with [redux-persist](https://github.com/rt2zz/redux-persist), create the following `storage` object:

```ts
import { Storage } from 'redux-persist'
import { MMKV } from "react-native-mmkv"

const storage = new MMKV()

export const reduxStorage: Storage = {
setItem: (key, value) => {
storage.set(key, value)
return Promise.resolve(true)
},
getItem: (key) => {
const value = storage.getString(key)
return Promise.resolve(value)
},
removeItem: (key) => {
storage.delete(key)
return Promise.resolve()
},
}
```
23 changes: 23 additions & 0 deletions docs/WRAPPER_ZUSTAND_PERSIST_MIDDLEWARE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# zustand persist-middleware wrapper

If you want to use MMKV with [zustand persist-middleware](https://github.com/pmndrs/zustand#persist-middleware), create the following `storage` object:

```ts
import { StateStorage } from 'zustand/middleware'
import { MMKV } from 'react-native-mmkv'

const storage = new MMKV()

const zustandStorage: StateStorage = {
setItem: (name, value) => {
return storage.set(name, value)
},
getItem: (name) => {
const value = storage.getString(name)
return value ?? null
},
removeItem: (name) => {
return storage.delete(name)
},
}
```

0 comments on commit a3c096e

Please sign in to comment.