diff --git a/docs/reference/components/editor.md b/docs/reference/components/editor.md index 7270ec85d..4fb8ed156 100644 --- a/docs/reference/components/editor.md +++ b/docs/reference/components/editor.md @@ -12,8 +12,6 @@ The top-level React component that renders the Slate editor itself. - [`autoFocus`](#autofocus) - [`className`](#classname) - [`onChange`](#onchange) - - [`onDocumentChange`](#ondocumentchange) - - [`onSelectionChange`](#onselectionchange) - [`plugins`](#plugins) - [`readOnly`](#readonly) - [`role`](#role) @@ -53,8 +51,6 @@ The top-level React component that renders the Slate editor itself. autoFocus={Boolean} className={String} onChange={Function} - onDocumentChange={Function} - onSelectionChange={Function} plugins={Array} readOnly={Boolean} role={String} @@ -85,16 +81,6 @@ An optional class name to apply to the content editable element. A change handler that will be called with the `change` that applied the change. You should usually pass the newly changed `change.state` back into the editor through its `state` property. This hook allows you to add persistence logic to your editor. -### `onDocumentChange` -`Function onDocumentChange(document: Document, change: Change)` - -A convenience handler property that will only be called for changes in state where the document has changed. It is called with the changed `document` and `change`. - -### `onSelectionChange` -`Function onSelectionChange(selection: Selection, change: Change)` - -A convenience handler property that will only be called for changes in state where the selection has changed. It is called with the changed `selection` and `change`. - ### `plugins` `Array` diff --git a/docs/reference/plugins/plugin.md b/docs/reference/plugins/plugin.md index 34b9815ba..14e0fe1b5 100644 --- a/docs/reference/plugins/plugin.md +++ b/docs/reference/plugins/plugin.md @@ -202,7 +202,7 @@ The `data` object contains a State [`Selection`](../models/selection.md) object If no other plugin handles this event, it will be handled by the [Core plugin](./core.md). -_Note: This is **not** Slate's internal selection representation (although it mirrors it). If you want to get notified when Slate's selection changes, use the [`onSelectionChange`](../components/editor.md#onselectionchange) property of the ``. This handler is instead meant to give you lower-level access to the DOM selection handling, which **is not always triggered** as you'd expect._ +_Note: This is **not** Slate's internal selection representation (although it mirrors it). If you want to get notified when Slate's selection changes, use the [`onChange`](../components/editor.md#onchange) property of the ``. This handler is instead meant to give you lower-level access to the DOM selection handling, which **is not always triggered** as you'd expect._ ## Other Properties diff --git a/docs/walkthroughs/saving-and-loading-html-content.md b/docs/walkthroughs/saving-and-loading-html-content.md index a75f4e59b..41df6043e 100644 --- a/docs/walkthroughs/saving-and-loading-html-content.md +++ b/docs/walkthroughs/saving-and-loading-html-content.md @@ -239,23 +239,21 @@ class App extends React.Component { } onChange = ({ state }) => { + // When the document changes, save the serialized HTML to Local Storage. + if (state.document != this.state.state.document) { + const string = html.serialize(state) + localStorage.setItem('content', string) + } + this.setState({ state }) } - // When the document changes, save the serialized HTML to Local Storage. - onDocumentChange = (document, { state }) => { - const string = html.serialize(state) - localStorage.setItem('content', string) - } - render() { - // Add the `onDocumentChange` handler. return ( ) } diff --git a/docs/walkthroughs/saving-to-a-database.md b/docs/walkthroughs/saving-to-a-database.md index 0abe569f9..fcb4b9e76 100644 --- a/docs/walkthroughs/saving-to-a-database.md +++ b/docs/walkthroughs/saving-to-a-database.md @@ -56,11 +56,11 @@ class App extends React.Component { } onChange = ({ state }) => { - this.setState({ state }) - // Save the state to Local Storage. const content = Plain.serialize(state) localStorage.setItem('content', content) + + this.setState({ state }) } render() { @@ -93,10 +93,10 @@ class App extends React.Component { } onChange = ({ state }) => { - this.setState({ state }) - const content = Plain.serialize(state) localStorage.setItem('content', content) + + this.setState({ state }) } render() { @@ -113,9 +113,7 @@ class App extends React.Component { Now you should be able to save changes across refreshes! -However, if you inspect the change handler, you'll notice that it's actually saving the Local Storage value on _every_ change to the editor, even when only the selection changes! This is because `onChange` is called for _every_ change. For Local Storage this doesn't really matter, but if you're saving things to a database via HTTP request this would result in a lot of unnecessary requests. - -Instead of using `onChange`, Slate's editor also accepts an `onDocumentChange` convenience handler that you can use to isolate saving logic to only happen when the document itself has changed, like so: +However, if you inspect the change handler, you'll notice that it's actually saving the Local Storage value on _every_ change to the editor, even when only the selection changes! This is because `onChange` is called for _every_ change. For Local Storage this doesn't really matter, but if you're saving things to a database via HTTP request this would result in a lot of unnecessary requests. You can fix this by checking against the previous `document` value. ```js const initialContent = ( @@ -129,22 +127,20 @@ class App extends React.Component { } onChange = ({ state }) => { + // Check to see if the document has changed before saving. + if (state.document != this.state.state.document) { + const content = Plain.serialize(state) + localStorage.setItem('content', content) + } + this.setState({ state }) } - // Pull the saving logic out into the `onDocumentChange` handler. - onDocumentChange = (document, { state }) => { - const content = Plain.serialize(state) - localStorage.setItem('content', content) - } - render() { - // Add the `onDocumentChange` handler to the editor. return ( ) } @@ -177,13 +173,13 @@ class App extends React.Component { } onChange = ({ state }) => { - this.setState({ state }) - } + if (state.document != this.state.state.document) { + // Switch to using the Raw serializer. + const content = JSON.stringify(Raw.serialize(state)) + localStorage.setItem('content', content) + } - onDocumentChange = (document, { state }) => { - // Switch to using the Raw serializer. - const content = JSON.stringify(Raw.serialize(state)) - localStorage.setItem('content', content) + this.setState({ state }) } render() { @@ -191,7 +187,6 @@ class App extends React.Component { ) } diff --git a/src/components/editor.js b/src/components/editor.js index 58525f401..8645869ff 100644 --- a/src/components/editor.js +++ b/src/components/editor.js @@ -7,6 +7,7 @@ import Types from 'prop-types' import Stack from '../models/stack' import State from '../models/state' import SlateTypes from '../utils/prop-types' +import logger from '../utils/logger' import noop from '../utils/noop' /** @@ -71,8 +72,6 @@ class Editor extends React.Component { className: Types.string, onBeforeChange: Types.func, onChange: Types.func, - onDocumentChange: Types.func, - onSelectionChange: Types.func, placeholder: Types.any, placeholderClassName: Types.string, placeholderStyle: Types.object, @@ -96,8 +95,6 @@ class Editor extends React.Component { autoFocus: false, autoCorrect: true, onChange: noop, - onDocumentChange: noop, - onSelectionChange: noop, plugins: [], readOnly: false, schema: {}, @@ -137,6 +134,14 @@ class Editor extends React.Component { this.onChange(change) } } + + if (props.onDocumentChange) { + logger.deprecate('0.22.10', 'The `onDocumentChange` prop is deprecated because it led to confusing UX issues, see https://github.com/ianstormtaylor/slate/issues/614#issuecomment-327868679') + } + + if (props.onSelectionChange) { + logger.deprecate('0.22.10', 'The `onSelectionChange` prop is deprecated because it led to confusing UX issues, see https://github.com/ianstormtaylor/slate/issues/614#issuecomment-327868679') + } } /** @@ -239,8 +244,8 @@ class Editor extends React.Component { if (state == this.state.state) return onChange(change) - if (state.document != document) onDocumentChange(state.document, change) - if (state.selection != selection) onSelectionChange(state.selection, change) + if (onDocumentChange && state.document != document) onDocumentChange(state.document, change) + if (onSelectionChange && state.selection != selection) onSelectionChange(state.selection, change) } /**