【发布时间】:2019-08-24 20:45:32
【问题描述】:
我正在尝试测试一个自定义的 React 钩子。
我不明白为什么 setInterval 中的回调函数运行时没有使用新的上下文。
@testing-library/react 不存在问题,因为它可以使用新的上下文重新渲染。很可能在 useContext、useEffect 和 setInterval 之间发生了一些事情,但我不知道是什么。
自定义 React 钩子'useCustomContext.ts':
import { useContext, useEffect, useRef, createContext } from 'react';
export const CustomContext = createContext('');
export const useValueFromContext = function() {
const context = useContext(CustomContext);
const ref = useRef('');
function getContext() {
return context;
}
useEffect(() => {
ref.current = getContext();
const interval = setInterval(() => {
ref.current = getContext();
}, 1000);
return () => clearInterval(interval);
}, []);
return ref.current;
};
export default useValueFromContext;
测试“useCustomContext.test.tsx”失败:
import React from 'react';
import { useValueFromContext, CustomContext } from './useCustomContext';
import { render } from '@testing-library/react';
test('Should return value from most recently provided context', async () => {
const Component = () => {
const value = useValueFromContext();
return <span data-testid="context">{value}</span>;
};
const { getByTestId, rerender } = render(
<CustomContext.Provider value="a">
<Component />
</CustomContext.Provider>,
);
rerender(
<CustomContext.Provider value="b">
<Component />
</CustomContext.Provider>,
);
await new Promise(resolve => {
setTimeout(() => {
rerender(
<CustomContext.Provider value="b">
<Component />
</CustomContext.Provider>,
);
resolve();
}, 2000);
});
expect(getByTestId('context').textContent).toBe('b');
});
输出:
Should return value from most recently provided context
expect(received).toBe(expected) // Object.is equality
Expected: "b"
Received: "a"
【问题讨论】:
标签: reactjs react-hooks react-testing-library