1
0
mirror of https://github.com/ianstormtaylor/slate.git synced 2025-09-02 11:42:53 +02:00

deprecate onDocumentChange and onSelectionChange, fixes #614 (#1081)

This commit is contained in:
Ian Storm Taylor
2017-09-07 11:51:45 -07:00
committed by GitHub
parent c3caa2878c
commit 976af2cda1
5 changed files with 35 additions and 51 deletions

View File

@@ -12,8 +12,6 @@ The top-level React component that renders the Slate editor itself.
- [`autoFocus`](#autofocus) - [`autoFocus`](#autofocus)
- [`className`](#classname) - [`className`](#classname)
- [`onChange`](#onchange) - [`onChange`](#onchange)
- [`onDocumentChange`](#ondocumentchange)
- [`onSelectionChange`](#onselectionchange)
- [`plugins`](#plugins) - [`plugins`](#plugins)
- [`readOnly`](#readonly) - [`readOnly`](#readonly)
- [`role`](#role) - [`role`](#role)
@@ -53,8 +51,6 @@ The top-level React component that renders the Slate editor itself.
autoFocus={Boolean} autoFocus={Boolean}
className={String} className={String}
onChange={Function} onChange={Function}
onDocumentChange={Function}
onSelectionChange={Function}
plugins={Array} plugins={Array}
readOnly={Boolean} readOnly={Boolean}
role={String} 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. 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` ### `plugins`
`Array` `Array`

View File

@@ -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). 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 `<Editor>`. 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 `<Editor>`. 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 ## Other Properties

View File

@@ -239,23 +239,21 @@ class App extends React.Component {
} }
onChange = ({ state }) => { 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 }) 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() { render() {
// Add the `onDocumentChange` handler.
return ( return (
<Editor <Editor
schema={this.state.schema} schema={this.state.schema}
state={this.state.state} state={this.state.state}
onChange={this.onChange} onChange={this.onChange}
onDocumentChange={this.onDocumentChange}
/> />
) )
} }

View File

@@ -56,11 +56,11 @@ class App extends React.Component {
} }
onChange = ({ state }) => { onChange = ({ state }) => {
this.setState({ state })
// Save the state to Local Storage. // Save the state to Local Storage.
const content = Plain.serialize(state) const content = Plain.serialize(state)
localStorage.setItem('content', content) localStorage.setItem('content', content)
this.setState({ state })
} }
render() { render() {
@@ -93,10 +93,10 @@ class App extends React.Component {
} }
onChange = ({ state }) => { onChange = ({ state }) => {
this.setState({ state })
const content = Plain.serialize(state) const content = Plain.serialize(state)
localStorage.setItem('content', content) localStorage.setItem('content', content)
this.setState({ state })
} }
render() { render() {
@@ -113,9 +113,7 @@ class App extends React.Component {
Now you should be able to save changes across refreshes! 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. 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.
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:
```js ```js
const initialContent = ( const initialContent = (
@@ -129,22 +127,20 @@ class App extends React.Component {
} }
onChange = ({ state }) => { 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 }) 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() { render() {
// Add the `onDocumentChange` handler to the editor.
return ( return (
<Editor <Editor
state={this.state.state} state={this.state.state}
onChange={this.onChange} onChange={this.onChange}
onDocumentChange={this.onDocumentChange}
/> />
) )
} }
@@ -177,13 +173,13 @@ class App extends React.Component {
} }
onChange = ({ state }) => { 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 }) => { this.setState({ state })
// Switch to using the Raw serializer.
const content = JSON.stringify(Raw.serialize(state))
localStorage.setItem('content', content)
} }
render() { render() {
@@ -191,7 +187,6 @@ class App extends React.Component {
<Editor <Editor
state={this.state.state} state={this.state.state}
onChange={this.onChange} onChange={this.onChange}
onDocumentChange={this.onDocumentChange}
/> />
) )
} }

View File

@@ -7,6 +7,7 @@ import Types from 'prop-types'
import Stack from '../models/stack' import Stack from '../models/stack'
import State from '../models/state' import State from '../models/state'
import SlateTypes from '../utils/prop-types' import SlateTypes from '../utils/prop-types'
import logger from '../utils/logger'
import noop from '../utils/noop' import noop from '../utils/noop'
/** /**
@@ -71,8 +72,6 @@ class Editor extends React.Component {
className: Types.string, className: Types.string,
onBeforeChange: Types.func, onBeforeChange: Types.func,
onChange: Types.func, onChange: Types.func,
onDocumentChange: Types.func,
onSelectionChange: Types.func,
placeholder: Types.any, placeholder: Types.any,
placeholderClassName: Types.string, placeholderClassName: Types.string,
placeholderStyle: Types.object, placeholderStyle: Types.object,
@@ -96,8 +95,6 @@ class Editor extends React.Component {
autoFocus: false, autoFocus: false,
autoCorrect: true, autoCorrect: true,
onChange: noop, onChange: noop,
onDocumentChange: noop,
onSelectionChange: noop,
plugins: [], plugins: [],
readOnly: false, readOnly: false,
schema: {}, schema: {},
@@ -137,6 +134,14 @@ class Editor extends React.Component {
this.onChange(change) 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 if (state == this.state.state) return
onChange(change) onChange(change)
if (state.document != document) onDocumentChange(state.document, change) if (onDocumentChange && state.document != document) onDocumentChange(state.document, change)
if (state.selection != selection) onSelectionChange(state.selection, change) if (onSelectionChange && state.selection != selection) onSelectionChange(state.selection, change)
} }
/** /**