4

MobX では、すべての値を再設定せずに、監視可能な配列全体に新しい値を設定するにはどうすればよいですか?

最初に考えられるのは次のとおりです。

let arr = observable([]);
autorun(() => {
  console.log('my array changed!');
});
arr = ['foo', 'bar'];

しかし、それautorunobservable array.

それで、これを行う正しい方法は何ですか?

これに対する私の解決策は、セッターで別の変数を使用し、セッター関数内で、観測可能な配列インデックスindexで変更し、インデックスを置換、追加、および削除することでした。このような:

( jsFiddle はこちら)

const {observable, computed, extendObservable} = mobx;
const {observer} = mobxReact;
const {Component} = React;
const {render} = ReactDOM
const {autorun} = mobx

class Store {
    @observable entries = [1,2,3,4,5];
    set rows(arr) {
        // add new values
        for (let i = 0, l = arr.length; i < l; i++) {
            this.entries[i] = arr[i];
        }
        // remove rest of entries
        let diff = this.entries.length - arr.length;
        if (diff > 0) {
            while (diff > 0) {
                this.entries.pop();
                diff--;
            }
        }
    }
}
const store = new Store();

@observer
class App extends Component {
    updateRows(){
        return this.props.entries.map(
            (row, i) => <p key={i}>{row}</p>
        );
    }
    render() {
        const rows = this.updateRows();
        return <div>{rows}</div>;
    }
}

setTimeout(() => {
    store.rows = ['foo', 'bar'];
    document.body.innerHTML += 'Timeout fired...';
}, 1000);


render(
    <App entries={store.entries} />,
    document.getElementById('mount')
);

これは正しい方法ですか?
または、同じ変数を使用して配列全体に値を再割り当てする方法はありますか?

4

1 に答える 1

10

TLDR; 使用するstore.entries.replace(['foo', 'bar']);

.replace()配列全体のコンテンツを置き換えてレンダリングをトリガーするメソッドを見つけました。メソッドについての提案の後にそ​​れを見つけ、そこからドキュメントclear()をより注意深く調べました

.replace(newItems);

配列内のすべての既存のエントリを新しいものに置き換えます。

コードは次のようになります。

( jsFiddle )

const {observable, autorun} = mobx;

class Store {
     @observable arr = [1,2,3,4,5];
}
const store = new Store();
autorun(() => {
  console.log('my array changed!', store.arr.slice());
});
setTimeout(() => {
   store.arr.replace(['foo', 'bar']);
}, 1000);

コード全体は次のようになります。

( jsFiddle )

const {observable, computed, extendObservable} = mobx;
const {observer} = mobxReact;
const {Component} = React;
const {render} = ReactDOM
const {autorun} = mobx

class Store {
     @observable entries = [1,2,3,4,5];
}
const store = new Store();

@observer
class App extends Component {
    updateRows(){
        return this.props.entries.map(
            (row, i) => <p key={i}>{row}</p>
        );
    }
  render() {
  const rows = this.updateRows();
    return <div>{rows}</div>;
  }
}

setTimeout(() => {
    store.entries.replace(['foo', 'bar']);
}, 1000);


render(
  <App entries={store.entries} />,
  document.getElementById('mount')
);
于 2016-12-18T10:59:42.250 に答える