简体   繁体   English

如何为整个MobX可观察数组设置新值

[英]How to set new values to whole MobX observable array

In MobX how can I set new values to a whole observable array without re-setting every value? 在MobX中,如何在不重新设置每个值的情况下为整个可观察数组设置新值?

First thought would be: 首先想到的是:

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

But that would not fire the autorun , I would just erased my observable array and replaced it with a new value/array. 但是这不会autorun ,我会删除我的observable array并用新值/数组替换它。

So, what is the correct way to do this? 那么,这样做的正确方法是什么?

My solution to this was to use another variable with a setter , and inside the setter function change the observable array index by index , replacing, adding and deleting indexes. 我此解决方案是使用另一个变量与一个设置器 ,以及设置器函数内由索引改变观察到的数组索引 ,置换,添加和删除的索引。 Like this: 像这样:

( jsFiddle here ) 这里是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')
);

Is this the correct way? 这是正确的方法吗?
or is there a way to just use the same variable to re-assign a value to the whole array? 或者有没有办法只使用相同的变量重新赋值给整个数组?

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

I found a method .replace() that will replace the content of the whole array and trigger the render. 我找到了一个方法.replace() ,它将替换整个数组的内容并触发渲染。 I found it after a suggestion about the clear() method and from there looking more carefully into the docs 关于clear()方法的建议之后找到它并从那里仔细查看文档

.replace(newItems);

Replaces all existing entries in the array with new ones. 用新的条目替换数组中的所有现有条目。

The code would then look like this: 代码将如下所示:

( jsFiddle ) 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);

The whole code would be: 整个代码是:

( jsFiddle ) 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')
);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM