javascript - Mobx Obervable Not Causing Observer Component To Update -
the requirement is:
when user changes input in dayview component, number of shifts in day instance changed input value (i.e. 4 in input means day.shifts.length == 4)
when day.shifts changes, dayview.rendershifts causes n rows rendered
however, changing input value works but,the dayview.render called once. should called again after day.shifts changed.
what missing?
here observer components:
//app.js import react 'react'; import store './shiftstore'; import { observer } 'mobx-react'; import { tojs } '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; and here mobx side:
//shiftstore.js import react 'react'; import {observable, computed, action, tojs } 'mobx'; class shift { @observable starttime = 10; @observable endtime = 9; @computed 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;
you never assigning shifts new array. use replace don't overwrite reference observable array:
@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); }
Comments
Post a Comment