question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

How to avoid a mass rerendering of everything that depends on only unchanged parts of a State object?

See original GitHub issue

Anytime a handler mutates the state, any component that gets state properties and inherits from BlazorStateComponent will automatically rerender. Right?

So that means that any component that depends on one part of that state but not another part will still rerender regardless of what part of the state they need. In other words, if my component shows MyState.A but not MyState.B, and there is a change to MyState.B, my component will rerender even though it doesn’t need to.

Suppose I enable a rather complex domain object to be edited piecemeal. So the user might edit a CommentsPanel that internally uses CurrentOrderState.OrderComments and a RushShippingPanel that internally uses CurrentOrderState.IsRushShipping, along with dozens of other properties. So now any change anywhere in the state will result in dozens of components being rerendered when it is more desirable that only one part at a time needs to be rerendered. Is there any way to get more granular with rerendering of components that inherit from BlazorStateComponent? It strikes me that rerendering everything that depends on a state object when anything in that state object changes (because it’s a whole new state each time) is a very blunt approach.

I am thinking there should be a way to avoid rerendering for unchanged parts of the state, as it is inevitable that even the simplest properties on a state object will themselves have properties, many of which won’t change.

Side note: I am using the term “rerender” for the process by which .NET (in WebAssembly) runs the C# code to figure out the overall presentation state of each component in memory. After that, OnAfterRender is called, then manipulating the DOM is a subsequent process. I try to avoid using the term “render” to mean “manipulating the DOM”, since it seems Microsoft uses it to mean running the C# code.

For pages of significant scope, rerendering can be the source of much slowness. If I am showing a 30x10 cell table, and each cell has 1-3 components in it, it can be quite burdensome to rerender (run the C# code to determine what the DOM should become) hundreds of components. So it would be nice if there was a way to avoid rerendering a component if the parts of the state it depends on have not changed. I have written a small package to do this apart from state management, but I was hoping that changes due to state management wouldn’t need such a thing (nor do I see a way to make them collaborate together).

Vue and React seem to automagically handle this (I think internally they compare previous state to new state on a per-property basis), but not so with Blazor (hence the need for StateHasChanged at all).

Issue Analytics

  • State:open
  • Created 2 years ago
  • Reactions:1
  • Comments:9 (4 by maintainers)

github_iconTop GitHub Comments

2reactions
szalapskicommented, Nov 16, 2021

Suppose I have a single-page app that might want state management to store the possible filter values for each of serveral fields in an advanced search, and the current value of each field, and the current search results, and the currently selected item in the search results, and whether that item’s detail is currently being shown. One component might show several of these pieces and another compnoent will show some of them as well as others. I think you would suggest I break up this into several state classes, and I agree…but it would be quite nice to have a single master state object where I can use Intellisense to find what I want in the state, so I can just reference what I want, e.g. getting State.Filters.DateRange.AllValues or State.SearchResults.First() or State.SearchResults[42].IsSelected or State.CurrentItem.IsOpen.

Now for example, say I have an action that toggles a boolean on one of the search results, (State.SearchResults[42].IsSelected) and the only thing in the whole state that renders differently based on that boolean value is one component in the several dozen used to show that component.

Ideally, any change to the state would not cause a rerender of thousands of components I am showing nor even the dozens for this item, but only the one that actually shows a check mark or a frowny face for State.SearchResults[42].IsSelected’s value. Ideally, I want to specify it at any level down the tree of objects in the state. so that other components used to show the items in the collection don’t rerender.

1reaction
szalapskicommented, Nov 29, 2021

As discussed on Discord, here’s a minimal demo of the rerendering issue #266 that I would like to help make nuanced: https://szalapski.github.io/BlazorRerenderReducers/blazor-state-demo And here’s the code: https://github.com/szalapski/BlazorRerenderReducers/tree/main/Sz.BlazorRerenderReducers/Client/BlazorStateDemo

Read more comments on GitHub >

github_iconTop Results From Across the Web

Discussion: How to avoid a mass rerendering of everything ...
I still am thinking there should be a way to avoid rerendering for unchanged parts of the state, as it is inevitable that...
Read more >
How to prevent re-rendering of components that have not ...
The simplest solution to your example is just create another component, and store the state with this. eg. ... In the above if...
Read more >
How I eliminate ALL unnecessary Rerenders in React
3. Use the useReducer hook. The useReducer hook is great for preventing a rerender on a state change. The reason why the useReducer...
Read more >
5 Ways to Avoid React Component Re-Renderings
1. Memoization using useMemo() and UseCallback() Hooks. Memoization enables your code to re-render components only if there's a change in the props. With...
Read more >
Re-rendering Components in ReactJS
A simple update of the state, from anywhere in the code, causes all the User Interface (UI) elements to be re-rendered automatically. However, ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found