我正在尝试测试自定义的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"
答案 0 :(得分:0)
我发现了问题。我必须像这样将上下文添加到useEffect依赖项:
useEffect(() => {
ref.current = getContext();
const interval = setInterval(() => {
ref.current = getContext();
}, 1000);
return () => clearInterval(interval);
}, [context]);