Controlled Mode state-updates, flickering
- [x] I have searched this repository's issues and believe that this is not a duplicate.
Current Behaviour
The problem occurs when working with, for example, RowDetailState or SelectionState in Controlled Mode.
Example RowDetailState:
When a row's expand-button is clicked, the new value is set to the internal state and the TableRowDetail-contentComponent is rendered immediately.
However, if expandedRowIds doesn't get set, it reverts back to its "old" state.
This causes unnecessary rendering and flickering.
The problem is amplified, when the onExpandedRowIdsChange is used to set expandedRowIds asynchronously.
Expected Behaviour
The components should not handle internal state, when being used in Controlled Mode. They should just reflect the current props.
Steps to Reproduce (for Bugs)
https://codesandbox.io/s/zn4ov8j2q3
RowDetailState demonstrates the first case, where the update is just ignored.
SelectionState demonstrates the second case, where the update is delayed.
Your Environment
devextreme-reactive: 1.1.2 react: 16.3.0 browser: Chrome bootstrap: none react-bootstrap: none material-ui: 1.0.0-beta.41
Hi,
Why do you treat such behavior as a bug? Could you please describe your scenario in greater detail?
Could you please describe your scenario in greater detail?
In my case I am using "fake rows" to populate the table:
[
{ id: 0 },
{ id: 1 },
{ id: 2 },
{ id: 3 },
{ id: 4 },
// etc...
]
I then use custom Cell-Components to handle the content. This way I need to process very little updates when cells change. Rows are dynamically loaded. While they are loading, there are dummys in their place. (The cells display grey bars where the text is going to be.)
I want my users to be unable to select/expand rows that are currently being loaded. The most reasonable way to achieve this - in my case - seems to be to simply not change the selected/expanded row when the corresponding callback is called.
That's when I noticed the flickering.
Why do you treat such behavior as a bug?
The idea of controlled mode is, that the component is being controlled. Meaning, that it doesn't handle user actions on its own, but rather passes on this information. The controlled component should only display what it's being told to display.
I treat this behavior as a bug, because at no point did my code tell the component to "check that box" or "expand that row". Regardless, the component acted on it's own (and checked the box) and later corrected itself (unchecked the box, which shouldn't have been checked in the first place), which causes flickering.
Thank you for the detailed explanation. I understand your concerns but currently, your scenario is not supported. We implemented our plugins to support controlled and uncontrolled modes at the same time. This adds limitations to plugin design, which causes a problem with supporting a fully controlled mode. So, we can't fix the issue currently as this will require huge changes in the current code. Moreover, these change can introduce more severe bugs. However, we will take your scenario into account and will improve the current behavior once we rework or refactor code related to the controlled and uncontrolled modes. As a workaround, I suggest you set a copy of a current state field. Here is an example, which works as expected: https://codesandbox.io/s/nkykq3lv8l Alternatively, you can use special templates for the 'select' and 'detail toggle' cells when row data is not loaded. I am going to mark this question as an enhancement. So, we will think about better plugin design in the future.