mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-09-01 19:22:35 +02:00
fix leaf to re-render when DOM is mismatched
This commit is contained in:
@@ -74,10 +74,11 @@ class Leaf extends React.Component {
|
|||||||
* Should component update?
|
* Should component update?
|
||||||
*
|
*
|
||||||
* @param {Object} props
|
* @param {Object} props
|
||||||
* @return {Boolean} shouldUpdate
|
* @return {Boolean}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
shouldComponentUpdate(props) {
|
shouldComponentUpdate(props) {
|
||||||
|
// If any of the regular properties have changed, re-render.
|
||||||
if (
|
if (
|
||||||
props.index != this.props.index ||
|
props.index != this.props.index ||
|
||||||
props.marks != this.props.marks ||
|
props.marks != this.props.marks ||
|
||||||
@@ -87,10 +88,18 @@ class Leaf extends React.Component {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
if (props.state.isBlurred) {
|
// If the DOM text does not equal the `text` property, re-render, this can
|
||||||
return false
|
// happen because React gets out of sync when previously natively rendered.
|
||||||
}
|
const el = findDeepestNode(ReactDOM.findDOMNode(this))
|
||||||
|
const text = this.renderText(props)
|
||||||
|
if (el.textContent != text) return true
|
||||||
|
|
||||||
|
// Otherwise, there aren't any content changes in this leaf, so if the
|
||||||
|
// selection is blurred we don't need to render to update it.
|
||||||
|
if (props.state.isBlurred) return false
|
||||||
|
|
||||||
|
// Otherwise, if it's focused, only re-render if this leaf contains one or
|
||||||
|
// both of the selection's edges.
|
||||||
const { index, node, state } = props
|
const { index, node, state } = props
|
||||||
const { start, end } = OffsetKey.findBounds(index, props.ranges)
|
const { start, end } = OffsetKey.findBounds(index, props.ranges)
|
||||||
return state.selection.hasEdgeBetween(node, start, end)
|
return state.selection.hasEdgeBetween(node, start, end)
|
||||||
@@ -187,10 +196,17 @@ class Leaf extends React.Component {
|
|||||||
this.debug('updateSelection')
|
this.debug('updateSelection')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render the leaf.
|
||||||
|
*
|
||||||
|
* @return {Element}
|
||||||
|
*/
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
this.debug('render')
|
this.debug('render')
|
||||||
|
|
||||||
const { node, index } = this.props
|
const { props } = this
|
||||||
|
const { node, index } = props
|
||||||
const offsetKey = OffsetKey.stringify({
|
const offsetKey = OffsetKey.stringify({
|
||||||
key: node.key,
|
key: node.key,
|
||||||
index
|
index
|
||||||
@@ -203,18 +219,20 @@ class Leaf extends React.Component {
|
|||||||
this.tmp.renders++
|
this.tmp.renders++
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<span
|
<span key={this.tmp.renders} data-offset-key={offsetKey}>
|
||||||
key={this.tmp.renders}
|
{this.renderMarks(props)}
|
||||||
data-offset-key={offsetKey}
|
|
||||||
>
|
|
||||||
{this.renderMarks()}
|
|
||||||
</span>
|
</span>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
renderText() {
|
/**
|
||||||
const { text, index, ranges } = this.props
|
* Render the text content of the leaf, accounting for browsers.
|
||||||
|
*
|
||||||
|
* @param {Object} props
|
||||||
|
* @return {Element}
|
||||||
|
*/
|
||||||
|
|
||||||
|
renderText({ text, index, ranges }) {
|
||||||
// If the text is empty, we need to render a <br/> to get the block to have
|
// If the text is empty, we need to render a <br/> to get the block to have
|
||||||
// the proper height.
|
// the proper height.
|
||||||
if (text == '') return <br />
|
if (text == '') return <br />
|
||||||
@@ -229,9 +247,16 @@ class Leaf extends React.Component {
|
|||||||
return text
|
return text
|
||||||
}
|
}
|
||||||
|
|
||||||
renderMarks() {
|
/**
|
||||||
const { marks, renderMark } = this.props
|
* Render all of the leaf's mark components.
|
||||||
const text = this.renderText()
|
*
|
||||||
|
* @param {Object} props
|
||||||
|
* @return {Element}
|
||||||
|
*/
|
||||||
|
|
||||||
|
renderMarks(props) {
|
||||||
|
const { marks, renderMark } = props
|
||||||
|
const text = this.renderText(props)
|
||||||
|
|
||||||
return marks.reduce((children, mark) => {
|
return marks.reduce((children, mark) => {
|
||||||
const Component = renderMark(mark, marks)
|
const Component = renderMark(mark, marks)
|
||||||
|
Reference in New Issue
Block a user