Ответ 1
Вы можете использовать shouldComponentUpdate, чтобы обновлять обновления компонентов или нет.
У меня есть таблица клиентов, и выбранный клиент хранится в ViewState
. Проблема в том, что все строки перерисовываются, когда выбор изменяется довольно медленно. В идеале, только выбранная строка и выбранная строка будут повторно отображены, но я не узнал, как этого добиться. Моя структура идентична примеру в Пример списка контактов MobX:
{this.filteredCustomers.map(customer => {
return (
<CustomerRow
key={customer.id}
customer={customer}
viewState={this.props.store.view}
/>
)
})}
и
const CustomerRow = observer((props: CustomerRowProps) => {
const isSelected = props.viewState.isCustomerSelected(props.customer)
const rowClass = isSelected ? 'active' : ''
return (
<tr className={rowClass}>
<td>{props.customer.lastName}</td>
<td>{props.customer.firstName}</td>
</tr>
)
})
Все строки зависят от значения ViewState.selectedCustomer
с помощью метода isCustomerSelected
.
Есть ли другой способ структурировать это, что позволяет избежать повторного рендеринга всех строк?
Вы можете использовать shouldComponentUpdate, чтобы обновлять обновления компонентов или нет.
Причина, по которой все строки перерисовываются, заключается в том, что props.viewState.isCustomerSelected(props.customer)
необходимо переоценить для каждого компонента наблюдателя при использовании наблюдаемого изменения.
Один из способов обойти это - использовать map, чтобы каждая запись имела потенциал checked
, так что только выделенные и невыбранные компоненты должны быть повторно отображены.
Пример (JSBin)
class AppState {
@observable todos = [
{
id: '1',
title: 'Do something'
},
{
id: '2',
title: 'Do something else'
},
{
id: '3',
title: 'Do a third thing'
}
]
}
var appState = new AppState();
@observer
class Todos extends React.Component {
checked = observable.map({});
changeTodo = (todo) => {
this.checked.clear();
this.checked.set(todo.id, true);
};
render() {
return <div>
<ul>
{ this.props.appState.todos.map((todo) =>
<Todo
todo={todo}
key={todo.id}
checked={this.checked}
onChange={() => this.changeTodo(todo)} />
) }
</ul>
<DevTools />
</div>;
}
}
@observer
class Todo extends React.Component {
render() {
const { todo, checked, onChange } = this.props;
const isChecked = checked.get(todo.id);
return <li>
<input
type="checkbox"
checked={isChecked}
onChange={onChange} />
{todo.title}
</li>;
}
}