slate: onDocumentChange not called on block type change

Hi @ianstormtaylor! I notice that if the block type changes (without any change to the text), the onDocumentChange is not being fired. Is that expected?

Intuitively, I would expect that a change in block type would be considered a material change in document, to invoke this event.

Here is a JSFiddle demonstrating this - https://jsfiddle.net/urr1z99g/1/

Steps to Reproduce

  1. Open console.
  2. Click on ‘Toggle Heading’ to start a heading.
  3. At this point, I would expect the onDocumentChange and onChange to be fired.

Thank you!

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 1
  • Comments: 26 (22 by maintainers)

Commits related to this issue

Most upvoted comments

Here’s a workaround for now:

  1. Keep using onDocumentChange to avoid needless updates.
  2. For externally initiated transforms (via buttons, keydown, etc), call the onChange method from your Editor instance directly, and pass in the transformed state.
  3. Call setState after calling onChange.

Example:

handler = () => {
  const resolvedState = this.state.state.transform().setBlock('header-one').apply();
  this.ref.onChange(resolvedState);
  this.setState({ state: resolvedState });
}

This did not result in any additional renders of the Editor component in my testing.

@ianstormtaylor I did spend a fair amount of time looking into a proper fix, but this seems to go pretty deep into Slate’s update lifecycle, and it’ll take more time to figure out what’s happening when (and why), and ensuring that a fix doesn’t cause regressions. This workaround should at least take this issue out of blocker territory for most folks.

So I took a little look at this problem. Yea, it does look like it’s a problem w/ all transformations that are called via Javascript.

onBeforeChange is called on Editor.componentWillReceiveProps. But onChange is called as a proxy through the EVENT_HANDLERS.

So here are some options:

  • Add a custom EVENT_HANDLER for the transformations
  • Somehow propagate onChange when in applyTransform
  • Call onChange in the componentWillReceiveProps

@ianstormtaylor, what do you think? I’m still learning how everything is architected so I don’t have an opinion yet.

This is a pretty major issue for persistence. It would be great to get some pointers on how to fix this up if you don’t have time to implement a fix yourself @ianstormtaylor

moreover, onChange is also not being fired on the change in block type. (Updated the url of the fiddle to reflect that).

@Slapbox no problem my friend 😃. Join us on the slack if you have anymore questions or want to brainstorm

@ianstormtaylor Interesting. I noticed it when dealing with toggling of blocks. Are you able to reproduce this super simplified JSFiddle - https://jsfiddle.net/urr1z99g/1/ ?

We are experiencing this, too. Seems to happen with all of our “outside” transforms, anything we call editor.onChange() for.

I have found that onBeforeChange() is still firing, though.