I have table of customers and the selected customer is stored in the ViewState
. The problem is that all rows re-render when the selection changes which is quite slow. Ideally only the selected row and the row previously selected would re-render, but I did not find out how to achieve this. My structure is identical to the example in the MobX contact list example:
{this.filteredCustomers.map(customer => {
return (
<CustomerRow
key={customer.id}
customer={customer}
viewState={this.props.store.view}
/>
)
})}
and
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>
)
})
All rows depend on the value of ViewState.selectedCustomer
through the isCustomerSelected
method.
Is there another way to structure this that avoids re-rendering all rows?
In your submit event handler use row ().data () to update the row's data then draw () to redraw the table. I tried doing with row ().data () , but i am actually creating cells in columns using createdcell (). They are not getting used. It is updating with normal values instead of the values from createdCell
You will need to send the row to the server to save in then DB then use draw () or ajax.reload () to refresh the table. Client side : Since i have to send multiple rows data on click of another button, with normal datatables ,i wanted to re-render only one row , the data for that row is in client side on clicking of row's save button.
I believe you can update the table display using row ().data () without the draw () but none of the callbacks, like rowCallback, will run without a draw event. Here is an example of why this is a problem. A user updates a row and the code displays it using row ().data (). The user searches or sorts the table. The updated data is now gone.
2.will rowcallback () gets called on row ().data ().draw ()---- but on using this it is actually making a call to the server (for server side) As we said if you are using server side processing you need to update the data in your server database then use draw () to fetch the updated row data.
The reason why all the rows are re-rendered is because props.viewState.isCustomerSelected(props.customer)
has to be re-evaluated for each observer component when the used observable change.
One way to get around this is to use a map so that every entry will have a potential checked
field of their own, so that only the selected and deselected components have to re-render.
Example (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>;
}
}
You can use shouldComponentUpdate to deside wheather component updates or not.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With