你应该将 react 钩子放在一个 react 函数组件中,而不是一个纯 JavaScript 高阶函数。
像这样重构它:
index.tsx:
import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
const IsFavorited = (Component) => {
return function Wrapper(props) {
const count = useSelector((state: any) => state.favourite.value);
if (count === 1) {
return <Component {...props} />;
}
return <span>No render</span>;
};
};
const CardLong = IsFavorited((props) => {
const count = useSelector((state: any) => state.favourite.value);
console.log('cardlong props.name:', props.name);
const dispatch = useDispatch();
return <div>card long</div>;
});
export default CardLong;
index.test.tsx:
import React from 'react';
import { render, unmountComponentAtNode } from 'react-dom';
import { act } from 'react-dom/test-utils';
import { Provider } from 'react-redux';
import createMockStore from 'redux-mock-store';
import CardLong from '.';
const mockStore = createMockStore();
describe('hoc hooks', () => {
let container;
beforeEach(() => {
container = document.createElement('div');
document.body.appendChild(container);
});
afterEach(() => {
unmountComponentAtNode(container);
container.remove();
container = null;
});
test('should no render', () => {
const store = mockStore({ favourite: { value: 123 } });
act(() => {
render(
<Provider store={store}>
<CardLong />
</Provider>,
container
);
});
expect(container!.innerHTML).toMatchInlineSnapshot(`"<span>No render</span>"`);
});
test('should render card long', () => {
const store = mockStore({ favourite: { value: 1 } });
act(() => {
render(
<Provider store={store}>
<CardLong name="teresa teng" />
</Provider>,
container
);
});
expect(container!.innerHTML).toMatchInlineSnapshot(`"<div>card long</div>"`);
});
});
测试结果:
PASS issues/hoc-hooks/index.test.tsx (8.031 s)
hoc hooks
✓ should no render (16 ms)
✓ should render card long (18 ms)
console.log
cardlong props.name: teresa teng
at issues/hoc-hooks/index.tsx:17:11
Test Suites: 1 passed, 1 total
Tests: 2 passed, 2 total
Snapshots: 2 passed, 2 total
Time: 8.541 s