Reactjs useEffect中的状态更改后,React钩子包装器未得到更新

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

当前行为

我正在使用一个功能组件,该组件带有useEffect中的setState挂钩。在useffect中设置的状态变量被包装在return语句上,以呈现组件的JSX

当我调试到它时,组件使用正确的状态变量呈现,但是我的测试中的包装器没有显示正确的信息

wrapper.update无法解决此问题

下面是我试图实现的一个片段:

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你的意思是把坐骑裹起来,对吗?