Skip to content

Component won't listen to observable changes #2

@FredrikSigvartsen

Description

@FredrikSigvartsen

Hi!

Thank you for a great starter. It's great to have a starter gatsby with mobx. But I'm having some issues regarding to mobx.

My code repo: https://github.com/FredrikSigvartsen/glowing-octo-couscous
Published at: https://quirky-chandrasekhar-6d307e.netlify.com/shop/positioning/

Some important files:
wrap-with-provider:

import React from 'react';
import { Provider } from 'mobx-react';

import ShopModel from './src/models/ShopModel';

// eslint-disable-next-line react/display-name,react/prop-types
export default ({ element }) => (
  <Provider shopStore={ShopModel}>{element}</Provider>
);

pages/shop/positioning.js:

import React from 'react';
import { inject, observer } from 'mobx-react';
import Counter from '../../components/Counter';
import Cage from '../../components/Cage';

// @observer
@inject('shopStore')
@observer
class PositioningSite extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      activeDrags: 0,
    };
  }

  onStart = () => {
    this.setState(prevState => ({ activeDrags: prevState.activeDrags + 1 }));
  };

  onStop = () => {
    this.setState(prevState => ({ activeDrags: prevState.activeDrags - 1 }));
  };

  render() {
    return (
      <>
        <section className="section is-large">
          <div className="container">
            <div id="drag-and-drop">
              {this.props.shopStore.cagesActive.map(cage => {
                return (
                  <Cage
                    key={cage.title}
                    className="box"
                    title={cage.title}
                    onStart={this.onStart}
                    onStop={this.onStop}
                  />
                );
              })}
            </div>
            <div>
              <h1>Place your box above</h1>
              <h3>
                <strong>Box {this.props.shopStore.compassDirection}</strong>
              </h3>

              <Counter
                title="Compass"
                counter={this.props.shopStore.compassDirection}
                onIncrement={() =>
                  this.props.shopStore.IncrementCompassDirection()
                }
                onDecrement={() =>
                  this.props.shopStore.DecrementCompassDirection()
                }
              />

              <h3>
                <strong>Cage</strong>
              </h3>
              <Counter
                title="Active"
                counter={this.props.shopStore.cagesActive.length}
                onIncrement={() => this.props.shopStore.AddActiveCage()}
                onDecrement={() => this.props.shopStore.RemoveLastActiveCage()}
              />
              <Counter
                title="Inactive"
                counter={this.props.shopStore.cagesInactive.length}
                onIncrement={() => this.props.shopStore.AddInactiveCage()}
                onDecrement={() =>
                  this.props.shopStore.RemoveLastInactiveCage()
                }
              />
            </div>
          </div>
        </section>
      </>
    );
  }
}

export default PositioningSite;

ShopModel.js:

import { observable, action, decorate } from 'mobx';

class ShopModel {
  compassDirection = -20;

  cagesActive = [{ title: '1' }, { title: '2' }];

  cagesInactive = [{ title: '103' }];

  AddActiveCage() {
    this.cagesActive.push({ title: `${this.cagesActive.length + 1}` });
  }

  RemoveLastActiveCage() {
    if (this.cagesActive.length > 0) {
      const removedCage = this.cagesActive.pop();
      return removedCage !== undefined;
    }
    return false;
  }

  AddInactiveCage() {
    this.cagesInactive.push({ title: `${this.cagesInactive.length + 1}` });
  }

  RemoveLastInactiveCage() {
    if (this.cagesInactive.length > 0) {
      const removedCage = this.cagesInactive.pop();
      return removedCage !== undefined;
    }
    return false;
  }

  DecrementCompassDirection() {
    this.compassDirection -= 1;
  }

  IncrementCompassDirection() {
    this.compassDirection += 1;
  }
}

decorate(ShopModel, {
  compassDirection: observable,
  cagesActive: observable,
  cagesInactive: observable,
  AddActiveCage: action,
  RemoveLastActiveCage: action,
  AddInactiveCage: action,
  RemoveLastInactiveCage: action,
  DecrementCompassDirection: action,
  IncrementCompassDirection: action,
});

const ShopStore = new ShopModel();

export default ShopStore;

Expected behaviour
In expect that when triggering an action, the observable will change, and then the React component would listen to that change, and then rerendering using new values.

Actual behaviour
When using gatsby develop the action is triggered and the observable change, but the React component won't change. Also when pushing this to Netlify the action is not triggered at all.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions