Reactjs useEffect中的状态更改后,React钩子包装器未得到更新
当前行为 我正在使用一个功能组件,该组件带有useEffect中的setState挂钩。在useffect中设置的状态变量被包装在return语句上,以呈现组件的JSX 当我调试到它时,组件使用正确的状态变量呈现,但是我的测试中的包装器没有显示正确的信息 wrapper.update无法解决此问题 下面是我试图实现的一个片段:Reactjs useEffect中的状态更改后,React钩子包装器未得到更新,reactjs,jestjs,react-hooks,enzyme,Reactjs,Jestjs,React Hooks,Enzyme,当前行为 我正在使用一个功能组件,该组件带有useEffect中的setState挂钩。在useffect中设置的状态变量被包装在return语句上,以呈现组件的JSX 当我调试到它时,组件使用正确的状态变量呈现,但是我的测试中的包装器没有显示正确的信息 wrapper.update无法解决此问题 下面是我试图实现的一个片段: const DummyComponent= ({}) => { const [selected, setSelected] = React.useState
const DummyComponent= ({}) => {
const [selected, setSelected] = React.useState(false);
useEffect(() => {
setSelected(true)
}, [someDependency])
return (
{
selected && (
<div id= 'container'>
{childComponents}
</div>)
}
);
})
it('test', () => {
const wrapper= mount( <DummyComponent /> );
wrapper = wrapper.update(); // this doesn't fix my problem
wrapper.find('#container')first().props().onClick();
expect(wrapper.toMatchSnapshot());
});
预期行为
在useEffect中进行状态更新后,应在测试用例中触发重新渲染,并应找到id为container的元素
注意:这与
问题在于,当您第一次装载组件时,它不会呈现任何内容,因为selected为false。所以,当你搜索“容器”时,你什么也得不到
如果更新足够了,那么它可能应该在wrapper.find之前执行,以便使用选定的true呈现组件。但是React是异步的,我怀疑这还不够…问题是,当您第一次装载组件时,它不会呈现任何内容,因为selected为false。所以,当你搜索“容器”时,你什么也得不到
如果更新足够了,那么它可能应该在wrapper.find之前执行,以便使用选定的true呈现组件。但是React是异步的,我怀疑这还不够…在我看来,您的真实代码可能存在其他一些问题,可能是在效果中调用了一些基于承诺的代码?。下面是一个基于您的代码片段的工作示例:
const DummyComponent = ({}) => {
const [selected, setSelected] = React.useState(false);
const [result, setResult] = React.useState("");
React.useEffect(() => {
setSelected(true);
}, []);
return selected && <div id='container' onClick={() => setResult("test")}>
<label>{result}</label>
</div>;
};
it('test', () => {
const wrapper = mount(<DummyComponent/>);
act(() => {
wrapper.find('#container').first().props().onClick();
});
expect(wrapper.find("label").text()).toEqual("test");
});
实际上,act仅用于与组件本身的交互,而不用于渲染后效果。在我看来,您的真实代码还存在一些其他问题,可能是在效果中调用了一些基于承诺的代码?。下面是一个基于您的代码片段的工作示例:
const DummyComponent = ({}) => {
const [selected, setSelected] = React.useState(false);
const [result, setResult] = React.useState("");
React.useEffect(() => {
setSelected(true);
}, []);
return selected && <div id='container' onClick={() => setResult("test")}>
<label>{result}</label>
</div>;
};
it('test', () => {
const wrapper = mount(<DummyComponent/>);
act(() => {
wrapper.find('#container').first().props().onClick();
});
expect(wrapper.find("label").text()).toEqual("test");
});
act实际上只用于与组件本身的交互,而不用于渲染后效果。我修复了我的问题,实际上我需要将我的组件分配到不同的包装器,然后更新包装器,然后检查包装器(而不是组件)上的更新。以下是片段:
it('test', () => {
const component= mount( <DummyComponent /> );
const wrapper = component.update();
wrapper.find('#container')first().props().onClick();
expect(wrapper.toMatchSnapshot());
});
这将有更新的组件我修复了我的问题,实际上我需要将我的组件分配给不同的包装,然后更新包装,然后检查包装上的更新,而不是组件。以下是片段:
it('test', () => {
const component= mount( <DummyComponent /> );
const wrapper = component.update();
wrapper.find('#container')first().props().onClick();
expect(wrapper.toMatchSnapshot());
});
这将有更新的组件它应该是。查找“容器”。@EstusFlask这是一个输入错误,我更正了我的问题。问题不是这个类型,您是否尝试过在act中包装呈现代码?在测试钩子时,它有助于解决很多问题。请提供可以重现问题的。没有任何依赖项和onClick。这意味着你的真实情况可能与你的不同posted@kidney你的意思是在act中包装坐骑,对吗?应该是。找到“容器”。@EstusFlask这是一个拼写错误,我更正了我的问题。问题不是这个类型,您是否尝试过在act中包装呈现代码?在测试钩子时,它有助于解决很多问题。请提供可以重现问题的。没有任何依赖项和onClick。这意味着你的真实情况可能与你的不同posted@kidney你的意思是把坐骑裹起来,对吗?