导致测试未停止的更新状态



我有一个React应用程序。我正在使用Jest和React测试库进行单元测试。

我必须测试一个组件。在组件的useEffect中,有一个API调用,一旦收到响应,我们就更新组件的本地状态。

const [data, setData] = useState({})
useEffect(()=>{
// Make API call to a custom fetch hook
},[])
useEffect(()=>{
setData(response.data) //response data is a JSON object
},[response])

测试文件代码片段如下-

const {getByTestId} = render(<MyComponent></MyComponent>)

我还没有放入任何断言,因为有无限运行的测试用例

我做了什么?我已经能够模拟fetch调用并执行setData。

问题-测试一直在运行。但是如果我改变响应。数据为布尔值或字符串或数字时,测试不会无限运行。另外,如果我在初始化状态中放置一个虚拟对象,测试将运行良好。

const [data, setData] = useState({
name: 'Test',
Age: '99'
})

useEffect中提供一个对象作为依赖不是一个好主意,因为即使对象中的数据保持不变,在每次渲染时-对象引用更改-效果将再次运行(即使其中的数据保持不变)。

解决这个问题的方法是使用JSON.stringify对依赖项进行字符串化。(虽然不建议对包含日期,符号,null或undefined等对象的数据进行操作)


useEffect(() => {
setData(response.data)
}, [JSON.stringify(response)]);

以上操作不应该影响你的UI。

另一个解决方案是存储之前的响应值,并在执行setData之前进行比较。您可以使用usePrevious钩子:

function usePrevious(value) {
const ref = useRef();
useEffect(() => {
ref.current = value;
});
return ref.current;
}

最新更新