Slate: onChange fires multiple times

Created on 8 Aug 2018  Â·  11Comments  Â·  Source: ianstormtaylor/slate

On default demo https://www.slatejs.org/#/history onChange fired many times.
3 times on simple focus (and increase history size), 3 times on any blur. Few times on any modifier like shift.

mm26f8cxul

When I add onChange on input field, this function triggered only when value is changed. So I can't detect when content is really changed.

bug ♥ help

Most helpful comment

In componentDidUpdate compare prevState.value.document and this.state.value.document

All 11 comments

@zhujinxuan thanx for this PR. I tried 0.37 version, but onChange fires at same times. Maybe it's not a bug, because change uses in blur and focus. And onChanges fired when I changing Range.
I think maybe it's normal behaviour, because selection is a part of value.

But how I can recognise when edited exactly content, not selection? Is it possible to add some flag for it? For example change.value.isContentChanged or change.value.selection.isChanged and change.value.document.isChanged or something like this.

Now I see only one way — manually compare documents from state and Change, but it's really ineffective -(

@bragovo I tried with https://www.slatejs.org/#/history , it seems slate:editor onChange fires only one time per rendering.

Can you check the version of slate-react you are using

The last one 0.15.9. Yes, one time when you open this page and one time on any focus and one time on any blur. But content not changed (except selection).. when you open page content initialised, not changed. When you focus editor — Undos +1 (this is bug I think). When you move pointer and change selection onChange fires on any changing symbol.

@bragovo I see. Currently we stores selection change in history stack and use componentDidUpdate to keep value.selection and dom selection consistent. I think it is reasonable that selection changes caused onChange if someone tries to implement an selection based normalization logic with slate.

Ok, is it possible to recognise selection or content changes?

@bragovo you can compare change.value with the previous change.value. If the reference changed, the value changed.

@bryanph yeah, but how? Value is not simple string, so change.value == this.state.values.text always false. I see only two ways compare each element or compare by hash, but is very long time operations.
https://stackoverflow.com/questions/201183/how-to-determine-equality-for-two-javascript-objects - there is no effective way to compare big object.

In componentDidUpdate compare prevState.value.document and this.state.value.document

@zhujinxuan thank you, it works for me.

I hate to perform necromancy here, but... I could be doing something wrong, but the documents are always equal for me ^

Was this page helpful?
0 / 5 - 0 ratings