Skip to content

Commit

Permalink
improve createStoreContext persistence key names
Browse files Browse the repository at this point in the history
  • Loading branch information
PabloSzx committed Mar 27, 2020
1 parent 948d77d commit 753b90a
Show file tree
Hide file tree
Showing 5 changed files with 205 additions and 73 deletions.
116 changes: 99 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@ yarn add react-state-selector

> Check **https://pabloszx.github.io/react-state-selector** for more detailed examples and use cases.
### TODOs
### Features

- [x] Redux DevTools
- [x] async actions
- [x] Redux **DevTools** support
- [x] **async** actions (_**redux-thunk** alike_)
- [x] **TypeScript** first class support
- [x] **_reselect_** createSelector support
- [ ] **More** examples and use cases (In progress...)
- [x] Easy and efficient **localStorage** data persistence

### Basic Usage

Expand Down Expand Up @@ -57,12 +57,12 @@ const {
},
},
actions: {
incrementA: (n: number) => draft => {
incrementA: (n: number) => (draft) => {
// Here you can mutate "draft", and immer will
// automatically make the immutable equivalent
draft.countA += n;
},
incrementB: (n: number) => draft => {
incrementB: (n: number) => (draft) => {
draft.countB += n;
},
},
Expand Down Expand Up @@ -126,12 +126,12 @@ const {
},
},
actions: {
incrementA: (n: number) => draft => {
incrementA: (n: number) => (draft) => {
// Here you can mutate "draft", and immer will
// automatically make the immutable equivalent
draft.countA += n;
},
incrementB: (n: number) => draft => {
incrementB: (n: number) => (draft) => {
draft.countB += n;
},
},
Expand Down Expand Up @@ -195,7 +195,7 @@ By default every created store gives a couple of out of the box functionality, i
- If you **don't** give it a function, it will work simply as a **state getter**, so you can check the global state anytime without any restriction.

```ts
const state = produce(draft => {
const state = produce((draft) => {
draft.a += 1;
});
console.log(produce() === state); // true
Expand All @@ -208,7 +208,7 @@ console.log(produce() === state); // true
- You shouldn't rely on this feature to transform the entire state as with [produce](#produce-functiondraft--void--tstore-tstore) or [custom actions](#custom-actions);

```ts
const state = await asyncProduce(async draft => {
const state = await asyncProduce(async (draft) => {
draft.users = await (await fetch("/api/users")).json();
});
console.log(produce() === state); // true
Expand Down Expand Up @@ -251,7 +251,7 @@ const IncrementComp = () => {
return (
<button
onClick={() =>
produce(draft => {
produce((draft) => {
draft.count += 1;
})
}
Expand Down Expand Up @@ -346,7 +346,7 @@ const Store = createStore(
{ a: 1 },
{
actions: {
increment: (n: number) => draft => {
increment: (n: number) => (draft) => {
draft.a += n;
},
},
Expand All @@ -356,7 +356,7 @@ const StoreCtx = createStore(
{ b: 1 },
{
actions: {
decrement: (n: number) => draft => {
decrement: (n: number) => (draft) => {
draft.b -= n;
},
},
Expand Down Expand Up @@ -407,21 +407,21 @@ const Store = createStore(
},
{
asyncActions: {
getData: produce => async bodyArgs => {
produce(draft => {
getData: (produce) => async (bodyArgs) => {
produce((draft) => {
draft.state = State.loading;
});

try {
const response = await axios.post("/data", bodyArgs);

produce(draft => {
produce((draft) => {
draft.state = State.complete;
draft.data = response.data;
});
} catch (err) {
console.error(err);
produce(draft => {
produce((draft) => {
draft.state = State.error;
});
}
Expand Down Expand Up @@ -461,6 +461,88 @@ const Data = () => {

> Keep in mind that you can mix common synchronous actions and async actions in a single store, but you should not repeat the action names in both objects.
### **localStorage** data persistence and \*_DevTools_

When creating an store via **createStore** or **createStoreContext** you can specify some field that enable some useful features:

```tsx
//createStoreContext(
createStore(
{
foo: "bar",
},
{
/**
* devName
*
* Activates the Redux DevTools for this store using
* this name as reference.
*/
devName: "fooBarStore",

/**
* devToolsInProduction
*
* Activates the Redux Devtools functionality in production.
*
* By default this is false
*/
devToolsInProduction: true,
storagePersistence: {
/**
* isActive
*
* Activates the data persistence in this store
**/
isActive: true,
/**
* persistenceKey
*
* Set the key used for the storage persistence method.
*
* It has to be a string, and if it's not specified
* reuses the "devName", but it has to exists at least one
* of these two if the storagePersistence is active
**/
persistenceKey: "fooBarStore",
/**
* debounceWait
*
* Calling an external store like localStorage every time
* any change to the store is very computationally expensive
* and that's why by default this functionality is being debounced
* to be called only when needed, after X amount of milliseconds
* since the last change to the store.
*
* By default it's set to 3000 ms, but you can customize it to
* be 0 if you want almost instant save to the persistence store
**/
debounceWait: 1000,
/**
* persistenceMethod
*
* You also can customize the persistence method,
* but by default uses window.localStorage.
*
* Keep in mind that it should follow the same API
* of setItem and getItem of localStorage
**/
persistenceMethod: window.localStorage,
/**
* isSSR
*
* Flag used to specify that this store is going to be
* used in server side rendering environments and it prevents
* client/server mismatched html on client side hydration
*
* false by default
**/
isSSR: true,
},
}
);
```

### **Map / Set** support _and/or_ **old browsers / React Native** support

In [Immer](https://immerjs.github.io/immer) latest version in order to reduce bundle size if you need support for **Map**, **Set**, **old browsers** or **React Native** you need to call some specific Immer functions as early as possible in your application.
Expand Down
9 changes: 4 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,14 @@
"@storybook/addon-storysource": "^5.3.17",
"@storybook/addons": "^5.3.17",
"@storybook/core": "^5.3.17",
"@storybook/preset-create-react-app": "^2.1.0",
"@storybook/preset-create-react-app": "^2.1.1",
"@storybook/react": "^5.3.17",
"@testing-library/jest-dom": "^5.1.1",
"@testing-library/jest-dom": "^5.3.0",
"@testing-library/react": "^10.0.1",
"@testing-library/react-hooks": "^3.2.1",
"@types/babel__core": "^7.1.6",
"@types/jest": "^25.1.4",
"@types/react": "^16.9.25",
"@types/react": "^16.9.26",
"@types/react-dom": "^16.9.5",
"@types/react-is": "^16.7.1",
"@types/react-test-renderer": "^16.9.2",
Expand All @@ -74,7 +74,7 @@
"husky": "^4.2.3",
"prettier": "^2.0.2",
"pretty-quick": "^2.0.1",
"react": "^16.13.0",
"react": "^16.13.1",
"react-docgen-typescript-loader": "^3.7.1",
"react-dom": "^16.13.1",
"react-is": "^16.13.1",
Expand All @@ -86,7 +86,6 @@
"tsdx": "^0.13.0",
"tslib": "^1.11.1",
"typescript": "^3.8.3",
"use-context-selector": "^1.1.0",
"wait-for-expect": "^3.0.2",
"webpack": "^4.42.1"
},
Expand Down
20 changes: 13 additions & 7 deletions src/createStoreContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,15 +203,21 @@ export function createStoreContext<
"For local storage persistence your store has to be an object"
);

const persistenceKey =
options.storagePersistence.persistenceKey ||
debugName ||
options.devName;
let persistenceKey: string | undefined;
if (options.storagePersistence.persistenceKey) {
persistenceKey = options.storagePersistence.persistenceKey;
} else if (options.devName) {
persistenceKey = options.devName;
}

if (!persistenceKey)
throw new Error(
"You have to specify persistence key, debugName or devName"
);
throw new Error("You have to specify persistence key or devName");

if (debugName) {
persistenceKey += "-" + debugName;
} else if (debugName === null) {
persistenceKey += "-" + "noProvider";
}

return connectPersistenceStorage({
persistenceKey,
Expand Down
Loading

0 comments on commit 753b90a

Please sign in to comment.