next-mobx-wrapper

0.4.0 • Public • Published

next-mobx-wrapper

NPM version NPM monthly download

Mobx wrapper for Next.js

⚠️ This will work only with Next.js 6+ ⚠️

Example: examples/with-mobx-wrapper

Installation

$ yarn add next-mobx-wrapper

Usage

Step 1: Wrap withMobx into _app.js

// pages/_app.js
 
import {withMobx} from 'next-mobx-wrapper';
import {configure} from 'mobx';
import {Provider, useStaticRendering} from 'mobx-react';
 
import * as getStores from '../stores';
 
const isServer = !process.browser;
 
configure({enforceActions: 'observed'});
useStaticRendering(isServer); // NOT `true` value
 
class MyApp extends App {
  render() {
    const {Component, pageProps, store} = this.props;
 
    return (
      <Container>
        <Provider {...store}>
          <Component {...pageProps} />
        </Provider>
      </Container>
    );
  }
}
 
export default withMobx(getStores)(MyApp);

Step 2: Create the stores

  • Create userStore sample:
// stores/user.js
 
import {BaseStore, getOrCreateStore} from 'next-mobx-wrapper';
import {observable, action, flow} from 'mobx';
import fetch from 'fetch';
 
class Store extends BaseStore {
  @observable userRegistry = new Map();
 
  fetchUser = flow(function*(id) {
    if (this.userRegistry.has(id)) {
      return;
    }
 
    try {
      const {data} = yield fetch(`https://api.domain.com/users/${id}`).then(
        response => response.json(),
      );
 
      this.userRegistry.set(id, data);
    } catch (error) {
      throw error;
    }
  });
 
  getUserById = id => {
    return this.userRegistry.get(id);
  };
}
 
// Make sure the store’s unique name
// AND must be same formula
// Example: getUserStore => userStore
// Example: getProductStore => productStore
export const getUserStore = getOrCreateStore('userStore', Store);
  • Create the rootStore:
// stores/index.js
 
export {getCounterStore} from './counter';
export {getUserStore} from './user';

Step 3: Binding data

  • Any pages
// pages/user.js
 
class User extends React.Component {
  static async getInitialProps({store: {userStore}, query}) {
    const {id} = query;
 
    await userStore.fetchUser(id);
 
    const user = userStore.getUserById(id);
 
    return {
      user,
    };
  }
 
  render() {
    const {user} = this.props;
    return <div>Username: {user.name}</div>;
  }
}
 
export default User;
  • Or any components
// components/UserInfo.jsx
 
import {inject} from 'mobx-react';
 
@inject(({userStore: {getUserById}}, props) => ({
  user: getUserById(props.id),
}))
class UserInfo extends React.Component {
  render() {
    return <div>Username: {this.props.user.name}</div>;
  }
}
 
// Somewhere
<SampleThing>
  <UserInfo id={9}>
</SampleThing>
  • Or with Hooks
// components/UserInfo.jsx
 
import React, {useMemo, useContext} from 'react';
import {MobXProviderContext} from 'mobx-react';
 
const UserInfo = ({id}) => {
  const {
    userStore: {getUserById},
  } = useContext(MobXProviderContext);
 
  const user = useMemo(() => getUserById(id), [id]);
 
  return <div>Username: {user.name}</div>;
};
 
export default UserInfo;

Note: Next.js 8 you need add more, if you want to use Observable Maps

//.babelrc
 
{
  "presets": [
    [
      "next/babel",
      {
        "transform-runtime": {
          "corejs": false
        }
      }
    ]
  ]
}

API

import {withMobx, BaseStore, getOrCreateStore} from 'next-mobx-wrapper';

License

MIT © Nghiep

/next-mobx-wrapper/

    Package Sidebar

    Install

    npm i next-mobx-wrapper

    Weekly Downloads

    36

    Version

    0.4.0

    License

    MIT

    Unpacked Size

    25.9 kB

    Total Files

    11

    Last publish

    Collaborators

    • tronghiep92