繁体   English   中英

React-testing-library - 避免重新渲染子组件

[英]React-testing-library - avoid rerender of child component

我正在尝试将测试从酶迁移到反应测试库

酶的目标是“如果孩子不受影响,不应该强制重新渲染孩子”

    const wasRendered = jest.fn();

    const Component = (props) => (
        <div {...props} />
    );

    const ChildComponent = () => {
        wasRendered();
        return <div>Hello</div>;
    };

    const SkinnableParent = Skinnable(config, Component); //Skinnable is a higher order component applied from our code. 
    const SkinnableChild = Skinnable(config, ChildComponent);

    const subject = mount(
        <SkinnableParent>
            <SkinnableChild />
        </SkinnableParent>
    );

    // Sending props to force parent to re-render
    subject.setProps({className: 'foo'});
    const expected = 1;
    const actual = wasRendered.mock.calls.length;

    expect(actual).toEqual(expected);

通过测试库,我正在尝试使用重新渲染功能。

    const wasRendered = jest.fn();
    
    const Component = (props) => {
        return <div {...props} />
    };

    const ChildComponent = () => {
        wasRendered();
        return <div>Hello</div>;
    };

    const SkinnableParent = Skinnable(config, Component); //Skinnable is a higher order component applied from our code. 
    const SkinnableChild = Skinnable(config, ChildComponent);

    const RootComponent = ({className}) => {
        return (
        <SkinnableParent className={className}>
            <SkinnableChild />
        </SkinnableParent>
        )
    };

    const {rerender} = render(<RootComponent />);

    rerender(<RootComponent className='foo' />);

    const expected = 1;
    const actual = wasRendered.mock.calls.length;

    expect(actual).toEqual(expected);

问题是 RTL 的实际结果是 2。 子组件也正在重新渲染。

有没有办法达到与之前酶实施相同的结果?

在该测试中没有什么可以阻止 ChildComponent 的重新呈现。 您的酶测试不是测试您认为的。 在这种情况下,停止从子组件重新渲染的唯一方法是用 React.memo 包装它

渲染父组件时,所有子组件都将重新渲染,除非被 memo 或 shouldComponentUpdate 实现返回 false 停止。

React 具有良好的性能,因为即使重新渲染组件,它也可能不需要在 DOM 中进行调解(这是繁重的计算负担。请参阅https://reactjs.org/docs/optimizing-performance.html#shouldcomponentupdate-in -行动

除非组件中的 JS 很昂贵,否则您不必担心避免重新渲染

查看这个沙箱,复制你的测试用例,你会看到它渲染了两次https://codesandbox.io/s/romantic-river-hcos6

在这种情况下,使用备忘录,它只会渲染一次https://codesandbox.io/s/condescending-lovelace-6z2j4

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM