当可观察的道具发生变化时,为什么这个React / Mobx观察者组件不重新渲染?

时间:2019-05-28 20:10:33

标签: javascript reactjs typescript mobx-react

我有一个React组件,该组件从其props渲染数据表。数据包装在MobX的observable()中。异步操作(AJAX调用)有时会向数据源添加新行,这将导致呈现新表行。不是这种情况。

有关组件的最小示例如下:

@observer
class MyDashboard extends React.Component {
    render() {
        return (
            <Table
                columns={this.props.columns}
                dataSource={this.props.model.contentTypes}
            />
        );
    }

    @action.bound
    private onThingHappened = async () => {
        const thing = await asyncThing();
        runInAction('onThingHappened', () => {
            this.props.model.contentTypes.push(thing);
        });
    }
}

道具model是一个可观察的对象。 model.contentTypes是一个对象数组。该表在第一次绘制时正确呈现;后来的重新渲染是有问题的。

如果删除了onThingHappened,绑定动作await将按预期工作。换句话说,在第一个await触发器触发之前发生的模型更改会按预期重新呈现。

runInAction似乎并没有明显改变。

但是,如果我在组件本身中绘制model.contentTypes-而不是简单地将其传递给子组件(在这种情况下为<Table>),则整个过程将按预期工作。例如:

    return (
        <React.Fragment>
            <div style={{display: 'none'}}>{this.props.model.contentTypes.length}</div>
            <Table
                columns={this.props.columns}
                dataSource={this.props.model.contentTypes}
            />
        </React.Fragment>
    )

在此渲染功能中,即使在model.contentTypes之后,反引用onThingHappened数组似乎也足以触发await中的重新渲染。

1 个答案:

答案 0 :(得分:0)

我不使用mobx,但经过一些研究:

  • <Table/>中包装observer()应该可以工作...如果<Table/>渲染器直接使用该值,则如果传递给(未包装的)子组件,它可能会失败;

“ Mobx跟踪访问” ,那么可能足以迫使mobx通过“不必要的”访问做出反应。

尝试某事:

render() {
  const amount = this.props.model.contentTypes.length;
  if( !amount ) return null; // to avoid 'amount unused, no unused ...'

  return (
    <Table
      columns={this.props.columns}
      dataSource={this.props.model.contentTypes}
    />
  );
}