Mobx Obervable不会导致Observer组件更新

时间:2017-09-12 15:46:18

标签: javascript reactjs mobx mobx-react

要求是:

  
      
  1. 当用户更改DayView组件中的输入时,该日实例中的班次数将更改为输入值(即输入中的4表示day.shifts.length == 4)

  2.   
  3. 当day.shifts发生变化时,DayView.renderShifts会导致N行呈现

  4.   

但是,更改输入值有效,但DayView.render只调用一次。它应该在day.shifts之后再次调用。

我错过了什么?

这是我的观察者组件

//App.js
import React from 'react';
import store from './ShiftStore';
import { observer } from 'mobx-react';
import { toJS } from 'mobx';

@observer class ShiftList extends React.Component {
  render() {
    return (
      <div>
        { store.days.map(
          (day, idx) => <DayView day={ day } key={ idx } />
        ) }
      </div>
    );
  }
}

@observer class DayView extends React.Component {
  renderShifts(day) {
    var rows = [];
    toJS(day.shifts).forEach(function(s) {
      rows.push(<div>Shift Row</div>)
    })
    return rows;
  }

  render() {
    const day = this.props.day;
    return (
      <div>
        <input
          type="number"
          onChange={(e) => day.resizeShifts(e.target.value)}/>
        {this.renderShifts(day)}
      </div>
    );
  }
}

class App extends React.Component {
  render() {
    return (
      <div className="App">
        <ShiftList/>
      </div>
    );
  }
}

export default App;

这是 mobx方

//ShiftStore.js
import React from 'react';
import {observable, computed, action, toJS } from 'mobx';

class Shift {
   @observable startTime = 10;
   @observable endTime = 9;
   @computed get duration() {
     let { startTime, endTime } = this;
     return endTime - startTime;
   }
}

class Day {
  @observable shifts = [];
  @action resizeShifts(n) {
    if (n < 0 || n % 1 !== 0) return;
    let { shifts, _resize } = this;
    let shiftArr = toJS(shifts);
    _resize(shiftArr, n, new Shift());
    shifts = shiftArr;
  }
  _resize(arr, newSize, defaultValue) {
      while(newSize > arr.length)
          arr.push(defaultValue);
      arr.length = newSize;
  }
}

class ShiftStore {
  constructor(props) {
    this.addDay = this.addDay.bind(this);
  }
  @observable days = [new Day()];
  addDay() { this.days.push(new Day()); }
}

const shiftStore = new ShiftStore();
export default shiftStore;

1 个答案:

答案 0 :(得分:1)

您永远不会为shifts分配新阵列。使用replace,这样就不会覆盖对可观察数组的引用:

@action resizeShifts(n) {
  if (n < 0 || n % 1 !== 0) return;
  let { shifts, _resize } = this;
  let shiftArr = toJS(shifts);
  _resize(shiftArr, n, new Shift());
  this.shifts.replace(shiftArr);
}