У меня есть компонент React, который рендерит таблицу данных из своих реквизитов. Данные обернуты в 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
.