1
0
mirror of https://github.com/ianstormtaylor/slate.git synced 2025-08-13 18:53:59 +02:00

Use equalityFn in useSlateSelector during render (#5848)

This commit is contained in:
Damjan Polugic
2025-04-29 16:30:41 +02:00
committed by GitHub
parent 0fde537b52
commit 2c62e01797
3 changed files with 79 additions and 1 deletions

View File

@@ -0,0 +1,5 @@
---
'slate-react': minor
---
Use equalityFn in useSlateSelector during render as well

View File

@@ -57,7 +57,13 @@ export function useSlateSelector<T>(
selector !== latestSelector.current || selector !== latestSelector.current ||
latestSubscriptionCallbackError.current latestSubscriptionCallbackError.current
) { ) {
selectedState = selector(getSlate()) const selectorResult = selector(getSlate())
if (equalityFn(latestSelectedState.current, selectorResult)) {
selectedState = latestSelectedState.current
} else {
selectedState = selectorResult
}
} else { } else {
selectedState = latestSelectedState.current selectedState = latestSelectedState.current
} }

View File

@@ -0,0 +1,67 @@
/* eslint-disable no-console */
import React, { useEffect } from 'react'
import { createEditor, Editor, Text, Transforms } from 'slate'
import { act, render, renderHook } from '@testing-library/react'
import {
Slate,
withReact,
Editable,
ReactEditor,
useSlateSelector,
} from '../src'
import _ from 'lodash'
describe('useSlateSelector', () => {
test('should use equality function when selector changes', async () => {
const editor = withReact(createEditor())
const initialValue = [{ type: 'block', children: [{ text: 'test' }] }]
const callback1 = jest.fn(() => [])
const callback2 = jest.fn(() => [])
const { result, rerender } = renderHook(
({ callback }) => useSlateSelector(callback, _.isEqual),
{
initialProps: {
callback: callback1,
},
wrapper: ({ children }) => (
<Slate editor={editor} initialValue={initialValue}>
<Editable />
{children}
</Slate>
),
}
)
// One call in the render body, and one call in the effect
expect(callback1).toBeCalledTimes(2)
const firstResult = result.current
await act(async () => {
Transforms.insertText(editor, '!', { at: { path: [0, 0], offset: 4 } })
})
// The new call is from the effect
expect(callback1).toBeCalledTimes(3)
// Return values should have referential equality because of the custom equality function
expect(firstResult).toBe(result.current)
// Callback 2 has not been used yet
expect(callback2).toBeCalledTimes(0)
// Re-render with new function identity
rerender({ callback: callback2 })
// Callback 1 is not called
expect(callback1).toBeCalledTimes(3)
// Callback 2 is used instead
expect(callback2).toBeCalledTimes(1)
// Return values should have referential equality because of the custom equality function
expect(firstResult).toBe(result.current)
})
})