mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-08-12 18:24:03 +02:00
Use equalityFn in useSlateSelector during render (#5848)
This commit is contained in:
@@ -57,7 +57,13 @@ export function useSlateSelector<T>(
|
||||
selector !== latestSelector.current ||
|
||||
latestSubscriptionCallbackError.current
|
||||
) {
|
||||
selectedState = selector(getSlate())
|
||||
const selectorResult = selector(getSlate())
|
||||
|
||||
if (equalityFn(latestSelectedState.current, selectorResult)) {
|
||||
selectedState = latestSelectedState.current
|
||||
} else {
|
||||
selectedState = selectorResult
|
||||
}
|
||||
} else {
|
||||
selectedState = latestSelectedState.current
|
||||
}
|
||||
|
67
packages/slate-react/test/use-slate-selector.test.tsx
Normal file
67
packages/slate-react/test/use-slate-selector.test.tsx
Normal 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)
|
||||
})
|
||||
})
|
Reference in New Issue
Block a user