reactjs - 访问 HOC 内部的 REDUX 状态
问题描述
首先,我通常是反应和编码的新手,并且已经陷入困境。
我正在尝试构建我可以收藏并在单独页面上呈现的组件。
我正在使用 redux 来存储组件的状态,无论它是否被收藏。
我遇到的问题是在我的HOC (isFavorited) 我无法访问 redux useSelector
const isFavorited = (Component) => {
const url = "URL"; //This will check wheater im on the page that I always want it rendering
const count = useSelector((state) => state.favourite.value); //Need to check weather the render state
console.log(Component);
if (count === 1 || url === "url") {
return (props) => <Component {...props} />;
}
return () => <span>No render</span>;
};
const CardLong = isFavorited((props) => {
const count = useSelector((state) => state.favourite.value);
const dispatch = useDispatch();
return (
**MY JSX IS HERE REMOVED FOR EASY READING**
);
});
export default CardLong;
解决方案
您应该将反应钩子放在反应函数组件中,而不是纯 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
推荐阅读
- javascript - Angular 中的 Bootstrap4 模态
- c++ - 通过右值引用而不是按值获取接收器参数以强制接口的高性能使用
- javascript - 在 JavaScript 中从字符串创建和下载文本文件:Blob/createObjectURL 与 encodeURIComponent
- apache-spark - Spark-Submit ClassNotFoundException 即使有包名
- linux - 多个 PCIe 卡:读取当前 PCIe 卡实例的设备树属性(在内核驱动程序内)
- javascript - 如何创建从输入字段中获取的 div 元素的数量
- python - 意外的程序故障-2
- r - mutate() 和使用 $ 在 dplyr 中添加列和在 R 中使用 tidyerse 之间的区别
- android - PHP + Android - 如何知道哪个用户正在尝试登录以及他是否已登录
- mysql - 如何根据两列对所有值求和