Skip to content
This repository was archived by the owner on Mar 11, 2021. It is now read-only.

Commit c472b63

Browse files
author
nghiepit
committed
add withMobx HOC
1 parent 6fb1584 commit c472b63

File tree

6 files changed

+101
-79
lines changed

6 files changed

+101
-79
lines changed

README.md

+31-77
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
88
:warning: This will work only with Next.js 6+ :warning:
99

10+
## Example: https://github.com/zeit/next.js/tree/canary/examples/with-mobx-wrapper
11+
1012
## Features
1113

1214
- Simple API, easy steps to set up
@@ -23,82 +25,20 @@ $ yarn add next-mobx-wrapper
2325

2426
## Usage
2527

26-
### Step 1: Injection multiple store
27-
28-
Below, we have two stores: `commonStore`, `userStore`
29-
30-
Create the `stores/with-mobx.js` file with the following minimal code:
31-
32-
```js
33-
// stores/with-mobx.js
34-
35-
import React from 'react';
36-
import {configure} from 'mobx';
37-
38-
import {getCommonStore} from './common';
39-
import {getUserStore} from './user'; // *Here*
40-
41-
configure({enforceActions: 'observed'});
42-
43-
export default App => {
44-
return class AppWithMobx extends React.Component {
45-
static async getInitialProps(appContext) {
46-
const commonStore = getCommonStore();
47-
const userStore = getUserStore(); // *Here*
48-
49-
// *Here*
50-
// Provide the store to getInitialProps of pages
51-
appContext.ctx.store = {
52-
commonStore,
53-
userStore,
54-
};
55-
56-
let appProps = {};
57-
if (typeof App.getInitialProps === 'function') {
58-
appProps = await App.getInitialProps.call(App, appContext);
59-
}
60-
61-
return {
62-
...appProps,
63-
initialMobxState: appContext.ctx.store,
64-
};
65-
}
66-
67-
constructor(props) {
68-
super(props);
69-
const {commonStore, userStore} = props.initialMobxState;
70-
71-
this.commonStore = getCommonStore(commonStore);
72-
this.userStore = getUserStore(userStore); // *Here*
73-
}
74-
75-
render() {
76-
// And *Here*
77-
return (
78-
<App
79-
{...this.props}
80-
store={{
81-
commonStore: this.commonStore,
82-
userStore: this.userStore,
83-
}}
84-
/>
85-
);
86-
}
87-
};
88-
};
89-
```
90-
91-
Wrap `HOC` to `_app.js`
28+
### Step 1: Wrap `withMobx HOC` to `_app.js`
9229

9330
```js
9431
// pages/_app.js
9532

9633
import ErrorPage from 'next/error';
34+
import {withMobx} from 'next-mobx-wrapper'; // *Here*
35+
import {configure} from 'mobx';
9736
import {Provider, useStaticRendering} from 'mobx-react';
98-
import withMobxStore from '../stores/with-mobx'; // *Here*
9937

10038
const isServer = !process.browser;
101-
useStaticRendering(isServer); // not `true` value
39+
40+
configure({enforceActions: 'observed'});
41+
useStaticRendering(isServer); // NOT `true` value
10242

10343
class MyApp extends App {
10444
static async getInitialProps({Component, ctx}) {
@@ -129,10 +69,12 @@ class MyApp extends App {
12969
}
13070
}
13171

132-
export default withMobxStore(MyApp); // *Here*
72+
export default withMobx(MyApp); // *Here*
13373
```
13474

135-
### Step 2: Create `userStore` sample
75+
### Step 2: Make stores
76+
77+
- Create `userStore` sample:
13678

13779
```js
13880
// stores/user.js
@@ -160,14 +102,26 @@ class Store extends BaseStore {
160102
};
161103
}
162104

163-
// *Here*
164105
// Make sure the store’s unique name
106+
// AND getCounterStore, counterStore must be same formula
107+
// Example: getUserStore => userStore
108+
// Example: getProductStore => productStore
165109
export const getUserStore = getOrCreateStore('userStore', Store);
166110
```
167111

112+
- Make the `rootStore`:
113+
114+
```js
115+
// stores/index.js
116+
// Just only simple
117+
118+
export {getCounterStore} from './counter';
119+
export {getUserStore} from './user';
120+
```
121+
168122
### Step 3: Binding data
169123

170-
Any page
124+
- Any pages
171125

172126
```js
173127
// pages/user.js
@@ -180,14 +134,14 @@ class User extends React.Component {
180134

181135
const user = userStore.getUserById(id);
182136

183-
if (user) {
137+
if (!user) {
184138
return {
185-
user,
139+
statusCode: 404,
186140
};
187141
}
188142

189143
return {
190-
statusCode: 404,
144+
user,
191145
};
192146
}
193147

@@ -203,7 +157,7 @@ class User extends React.Component {
203157
export default User;
204158
```
205159

206-
Or any component
160+
- Or any components
207161

208162
```js
209163
// components/UserInfo.jsx
@@ -232,7 +186,7 @@ class UserInfo extends React.Component {
232186
## API
233187

234188
```js
235-
import {BaseStore, getOrCreateStore} from 'next-mobx-wrapper';
189+
import {withMobx, BaseStore, getOrCreateStore} from 'next-mobx-wrapper';
236190
```
237191

238192
## License

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
"@babel/plugin-proposal-class-properties": "^7.1.0",
2121
"@babel/plugin-proposal-decorators": "^7.1.6",
2222
"next": "^7.0.2",
23+
"react": "^16.6.3",
2324
"rimraf": "^2.6.2"
2425
},
2526
"peerDependencies": {

src/index.js

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
export {default as withMobx} from './with-mobx';
12
import {isServer, mapToJson, jsonToMap} from './utils';
23

34
const __NEXT_MOBX_STORE__ = new Map();

src/utils.js

+4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
export const isServer = !process.browser;
22

3+
// getCounterStore=> counterStore
4+
export const getKeyNameStore = fnName =>
5+
fnName.replace(/^get(.)/, (match, p1) => p1.toLowerCase());
6+
37
export const mapToJson = map => {
48
try {
59
return JSON.stringify([...map]);

src/with-mobx.js

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import React from 'react';
2+
3+
import {getKeyNameStore} from './utils';
4+
5+
export default (getStores = {}) => App => {
6+
return class AppWithMobx extends React.Component {
7+
static async getInitialProps(appContext) {
8+
let appProps = {};
9+
10+
// Provide the store to getInitialProps of pages
11+
appContext.ctx.store = {};
12+
for (const fnName in getStores) {
13+
const storeKeyName = getKeyNameStore(fnName);
14+
appContext.ctx.store[storeKeyName] = getStores[fnName]();
15+
}
16+
17+
if (typeof App.getInitialProps === 'function') {
18+
appProps = await App.getInitialProps(appContext);
19+
}
20+
21+
return {
22+
...appProps,
23+
initialMobxState: appContext.ctx.store,
24+
};
25+
}
26+
27+
constructor(props) {
28+
super(props);
29+
this.store = {};
30+
31+
for (const fnName in getStores) {
32+
const storeKeyName = getKeyNameStore(fnName);
33+
this.store[storeKeyName] = getStores[fnName](
34+
props.initialMobxState[storeKeyName],
35+
);
36+
}
37+
}
38+
39+
render() {
40+
const {initialMobxState, ...rest} = this.props;
41+
return <App {...rest} store={{...this.store}} />;
42+
}
43+
};
44+
};

yarn.lock

+20-2
Original file line numberDiff line numberDiff line change
@@ -2812,7 +2812,7 @@ log-update@^2.3.0:
28122812
cli-cursor "^2.0.0"
28132813
wrap-ansi "^3.0.1"
28142814

2815-
loose-envify@^1.0.0, loose-envify@^1.3.1:
2815+
loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.1:
28162816
version "1.4.0"
28172817
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
28182818
integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
@@ -3563,7 +3563,7 @@ [email protected]:
35633563
object.assign "^4.1.0"
35643564
reflect.ownkeys "^0.2.0"
35653565

3566-
3566+
[email protected], prop-types@^15.6.2:
35673567
version "15.6.2"
35683568
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.2.tgz#05d5ca77b4453e985d60fc7ff8c859094a497102"
35693569
integrity sha512-3pboPvLiWD7dkI3qf3KbUe6hKFKa52w+AE0VCqECtf+QHAKgOL37tTaNCnuX1nAAQ4ZhyP+kYVKf8rLmJ/feDQ==
@@ -3678,6 +3678,16 @@ [email protected]:
36783678
resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-4.0.0.tgz#d198408a85b4070937a98667f500c832f86bd5d4"
36793679
integrity sha512-FlsPxavEyMuR6TjVbSSywovXSEyOg6ZDj5+Z8nbsRl9EkOzAhEIcS+GLoQDC5fz/t9suhUXWmUrOBrgeUvrMxw==
36803680

3681+
react@^16.6.3:
3682+
version "16.6.3"
3683+
resolved "https://registry.yarnpkg.com/react/-/react-16.6.3.tgz#25d77c91911d6bbdd23db41e70fb094cc1e0871c"
3684+
integrity sha512-zCvmH2vbEolgKxtqXL2wmGCUxUyNheYn/C+PD1YAjfxHC54+MhdruyhO7QieQrYsYeTxrn93PM2y0jRH1zEExw==
3685+
dependencies:
3686+
loose-envify "^1.1.0"
3687+
object-assign "^4.1.1"
3688+
prop-types "^15.6.2"
3689+
scheduler "^0.11.2"
3690+
36813691
read-pkg@^2.0.0:
36823692
version "2.0.0"
36833693
resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8"
@@ -3882,6 +3892,14 @@ sax@^1.2.4:
38823892
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
38833893
integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==
38843894

3895+
scheduler@^0.11.2:
3896+
version "0.11.2"
3897+
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.11.2.tgz#a8db5399d06eba5abac51b705b7151d2319d33d3"
3898+
integrity sha512-+WCP3s3wOaW4S7C1tl3TEXp4l9lJn0ZK8G3W3WKRWmw77Z2cIFUW2MiNTMHn5sCjxN+t7N43HAOOgMjyAg5hlg==
3899+
dependencies:
3900+
loose-envify "^1.1.0"
3901+
object-assign "^4.1.1"
3902+
38853903
schema-utils@^0.4.4, schema-utils@^0.4.5:
38863904
version "0.4.7"
38873905
resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.4.7.tgz#ba74f597d2be2ea880131746ee17d0a093c68187"

0 commit comments

Comments
 (0)