Best practice suggestion: display should reflect the slate.value model under (simulated) lag
See original GitHub issuePlease consider the following fiddle: link
I’ve set a setTimeout of 500ms to simulate a stressed computation load.
onChange({ value }) {
setTimeout(() => {
this.setState({ value });
}, 500);
}
In the first video i’ve type 1-9 quickly (less than 0.5 per key). the final text in a normal stress would have been “123456789”
In the second video i’ve long key pressed the right arrow key, moving the cursor from the start of the sentence it its end.
What’s the expected behavior?
Safe to say, lagged responsiveness is expected. But the UI should only display events that are stored to state.value. In the first examples, digit “1” should have not been temporarily displayed as it was not stored in the final state.value. In the second example, the cursor should have not move forward and jump back to what was stored in the state.value. It should have moved very slowly.
Issue Analytics
- State:
- Created 6 years ago
- Comments:8 (1 by maintainers)
Well, it’s the same thing. The
state.value
in the wrapping component is what’s given to thevalue
prop so it’s also the value inside the slate editor to which the change is applied. It’s just that in your example, the firststate.value
update does not happen for 500ms, so any subsequent changes that happen within that 500ms will be based on the non-updatedstate.value
. In other words, the fact that theonChange
has been called does not mean that the wrapping component’s state has been updated; with yoursetTimeout
the wrapping component’s state will not actually be updated for 500ms.Gotcha. So that’s actually already the behaviour in Slate. Keeping with the rapid-fire 1, 2, 3 from my last comment, consider this example timeline:
state.value
''
1
pressed, and queues asetTimeout
in 500ms''
2
pressed, and queues asetTimeout
in 500ms''
3
pressed, and queues asetTimeout
in 500ms''
1
fires and updates thestate.value
, Slate rerenders'1'
2
fires and updates thestate.value
, Slate rerenders'2'
3
fires and updates thestate.value
, Slate rerenders'3'
In essence, the flashing mirrors the amount of time between keypresses. At 505ms, Slate receives a new
value
prop saying the value is now'1'
. Slate rerenders to match what is then the currentstate.value
. It has no way of knowing that anothersetTimeout
is going to resolve again in a few ms and change the state again. Indeed, the flashing happens because Slate already does exactly what you suggest (precisely render what is provided in itsvalue
prop).